home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / vim-5.1 / src / fileio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-05  |  98.3 KB  |  4,062 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * fileio.c: read from and write to a file
  11.  */
  12.  
  13. #if defined(MSDOS) || defined(WIN32)
  14. # include <io.h>    /* for lseek(), must be before vim.h */
  15. #endif
  16.  
  17. #if defined __EMX__
  18. # include <io.h>    /* for mktemp(), CJW 1997-12-03 */
  19. #endif
  20.  
  21. #include "vim.h"
  22.  
  23. #ifdef HAVE_FCNTL_H
  24. # include <fcntl.h>
  25. #endif
  26.  
  27. #ifdef LATTICE
  28. # include <proto/dos.h>        /* for Lock() and UnLock() */
  29. #endif
  30.  
  31. #define BUFSIZE        8192        /* size of normal write buffer */
  32. #define SMBUFSIZE    256        /* size of emergency write buffer */
  33.  
  34. #ifdef VIMINFO
  35. static void check_marks_read __ARGS((void));
  36. #endif
  37. #ifdef UNIX
  38. static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime));
  39. #endif
  40. static void msg_add_fname __ARGS((BUF *, char_u *));
  41. static int msg_add_fileformat __ARGS((int eol_type));
  42. static void msg_add_lines __ARGS((int, long, long));
  43. static void msg_add_eol __ARGS((void));
  44. static int check_mtime __ARGS((BUF *buf, struct stat *s));
  45. static int  write_buf __ARGS((int, char_u *, int));
  46.  
  47. static linenr_t    write_no_eol_lnum = 0;    /* non-zero lnum when last line of
  48.                        next binary write should not have
  49.                        an end-of-line */
  50.  
  51.     void
  52. filemess(buf, name, s, attr)
  53.     BUF        *buf;
  54.     char_u    *name;
  55.     char_u    *s;
  56.     int        attr;
  57. {
  58.     msg_add_fname(buf, name);        /* put file name in IObuff with quotes */
  59.     STRCAT(IObuff, s);
  60.     /*
  61.      * For the first message may have to start a new line.
  62.      * For further ones overwrite the previous one, reset msg_scroll before
  63.      * calling filemess().
  64.      */
  65.     msg_start();
  66.     msg_outtrans_attr(IObuff, attr);
  67.     msg_clr_eos();
  68.     out_flush();
  69. }
  70.  
  71. /*
  72.  * Read lines from file 'fname' into the buffer after line 'from'.
  73.  *
  74.  * 1. We allocate blocks with lalloc, as big as possible.
  75.  * 2. Each block is filled with characters from the file with a single read().
  76.  * 3. The lines are inserted in the buffer with ml_append().
  77.  *
  78.  * (caller must check that fname != NULL, unless READ_STDIN is used)
  79.  *
  80.  * lines_to_skip is the number of lines that must be skipped
  81.  * lines_to_read is the number of lines that are appended
  82.  * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
  83.  *
  84.  * flags:
  85.  * READ_NEW    starting to edit a new buffer
  86.  * READ_FILTER    reading filter output
  87.  * READ_STDIN    read from stdin instead of a file
  88.  *
  89.  * return FAIL for failure, OK otherwise
  90.  */
  91.     int
  92. readfile(fname, sfname, from, lines_to_skip, lines_to_read, flags)
  93.     char_u    *fname;
  94.     char_u    *sfname;
  95.     linenr_t    from;
  96.     linenr_t    lines_to_skip;
  97.     linenr_t    lines_to_read;
  98.     int        flags;
  99. {
  100.     int        fd;
  101.     int        newfile = (flags & READ_NEW);
  102.     int        check_readonly;
  103.     int        filtering = (flags & READ_FILTER);
  104.     int        read_stdin = (flags & READ_STDIN);
  105.     char_u    c;
  106.     linenr_t    lnum = from;
  107.     char_u    *ptr = NULL;        /* pointer into read buffer */
  108.     char_u    *buffer = NULL;        /* read buffer */
  109.     char_u    *new_buffer = NULL;    /* init to shut up gcc */
  110.     char_u    *line_start = NULL;    /* init to shut up gcc */
  111.     colnr_t    len;
  112.     long    size;
  113.     char_u    *p;
  114.     long    filesize;
  115.     int        split = 0;        /* number of split lines */
  116. #define UNKNOWN     0x0fffffff        /* file size is unknown */
  117.     linenr_t    linecnt;
  118.     int        error = FALSE;        /* errors encountered */
  119.     int        ff_error = EOL_UNKNOWN; /* file format with errors */
  120.     long    linerest;        /* remaining chars in line */
  121. #ifdef UNIX
  122.     int        perm = 0;
  123. #endif
  124.     int        fileformat;        /* end-of-line format */
  125.     struct stat    st;
  126.     int        file_readonly;
  127.     linenr_t    skip_count;
  128.     linenr_t    read_count;
  129.     int        msg_save = msg_scroll;
  130.     linenr_t    read_no_eol_lnum = 0;   /* non-zero lnum when last line of
  131.                      * last read was missing the eol */
  132.     int        try_mac = (vim_strchr(p_ffs, 'm') != NULL);
  133.     int        try_dos = (vim_strchr(p_ffs, 'd') != NULL);
  134.     int        try_unix = (vim_strchr(p_ffs, 'x') != NULL);
  135.  
  136.  
  137. #ifdef AUTOCMD
  138.     write_no_eol_lnum = 0;    /* in case it was set by the previous read */
  139. #endif
  140.  
  141.     /*
  142.      * If there is no file name yet, use the one for the read file.
  143.      * b_notedited is set to reflect this.
  144.      * Don't do this for a read from a filter.
  145.      * Only do this when 'cpoptions' contains the 'f' flag.
  146.      */
  147.     if (curbuf->b_ffname == NULL && !filtering && !read_stdin &&
  148.                     vim_strchr(p_cpo, CPO_FNAMER) != NULL)
  149.     {
  150.     if (setfname(fname, sfname, FALSE) == OK)
  151.         curbuf->b_notedited = TRUE;
  152.     }
  153.  
  154.     if (shortmess(SHM_OVER) || curbuf->b_help)
  155.     msg_scroll = FALSE;    /* overwrite previous file message */
  156.     else
  157.     msg_scroll = TRUE;    /* don't overwrite previous file message */
  158.     if (sfname == NULL)
  159.     sfname = fname;
  160.     /*
  161.      * For Unix: Use the short file name whenever possible.
  162.      * Avoids problems with networks and when directory names are changed.
  163.      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
  164.      * another directory, which we don't detect.
  165.      */
  166. #if defined(UNIX) || defined(__EMX__)
  167.     fname = sfname;
  168. #endif
  169.  
  170.     /* set default 'fileformat' */
  171.     if (newfile && *p_ffs)
  172.     set_fileformat(default_fileformat());
  173.  
  174. #ifdef UNIX
  175.     /*
  176.      * On Unix it is possible to read a directory, so we have to
  177.      * check for it before the open().
  178.      */
  179.     if (!read_stdin)
  180.     {
  181.     perm = mch_getperm(fname);
  182. # ifdef _POSIX_SOURCE
  183.     if (perm >= 0 && !S_ISREG(perm)            /* not a regular file ... */
  184. #  ifdef S_ISFIFO
  185.               && !S_ISFIFO(perm)        /* ... or fifo or socket */
  186. #  endif
  187.                            )
  188. # else
  189.     if (perm >= 0 && (perm & S_IFMT) != S_IFREG /* not a regular file ... */
  190. #  ifdef S_IFIFO
  191.               && (perm & S_IFMT) != S_IFIFO /* ... or fifo ... */
  192. #  endif
  193. #  ifdef S_IFSOCK
  194.               && (perm & S_IFMT) != S_IFSOCK/* ... or socket */
  195. #  endif
  196.                         )
  197. # endif
  198.     {
  199. # ifdef _POSIX_SOURCE
  200.         if (S_ISDIR(perm))
  201. # else
  202.         if ((perm & S_IFMT) == S_IFDIR)
  203. # endif
  204.         filemess(curbuf, fname, (char_u *)"is a directory", 0);
  205.         else
  206.         filemess(curbuf, fname, (char_u *)"is not a file", 0);
  207.         msg_end();
  208.         msg_scroll = msg_save;
  209.         return FAIL;
  210.     }
  211.     }
  212. #endif
  213.  
  214.     /*
  215.      * When opening a new file we take the readonly flag from the file.
  216.      * Default is r/w, can be set to r/o below.
  217.      * Don't reset it when in readonly mode
  218.      * Only set/reset b_p_ro when BF_CHECK_RO is set.
  219.      */
  220.     check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
  221.     if (check_readonly && !readonlymode)    /* default: set file not readonly */
  222.     curbuf->b_p_ro = FALSE;
  223.  
  224.     if (newfile && !read_stdin)
  225.     {
  226.     if (stat((char *)fname, &st) >= 0)  /* remember time of file */
  227.     {
  228.         curbuf->b_mtime = st.st_mtime;
  229.         curbuf->b_mtime_read = st.st_mtime;
  230. #ifdef UNIX
  231.         /*
  232.          * Set the protection bits of the swap file equal to the original
  233.          * file. This makes it possible for others to read the name of the
  234.          * original file from the swapfile.
  235.          */
  236.         if (curbuf->b_ml.ml_mfp->mf_fname != NULL)
  237.         (void)mch_setperm(curbuf->b_ml.ml_mfp->mf_fname,
  238.                       (long)((st.st_mode & 0777) | 0600));
  239. #endif
  240.     }
  241.     else
  242.     {
  243.         curbuf->b_mtime = 0;
  244.         curbuf->b_mtime_read = 0;
  245.     }
  246.     }
  247.  
  248. /*
  249.  * for UNIX: check readonly with perm and access()
  250.  * for MSDOS and Amiga: check readonly by trying to open the file for writing
  251.  */
  252.     file_readonly = FALSE;
  253.     if (read_stdin)
  254.     fd = 0;
  255.     else
  256.     {
  257. #if defined(UNIX) || defined(DJGPP) || defined(__EMX__) || defined(VMS)
  258.     if (
  259. # ifdef UNIX
  260.         !(perm & 0222) ||
  261. # endif
  262.                 access((char *)fname, W_OK))
  263.         file_readonly = TRUE;
  264.     fd = open((char *)fname, O_RDONLY | O_EXTRA);
  265. #else
  266.     if (!newfile || readonlymode || (fd =
  267.                    open((char *)fname, O_RDWR | O_EXTRA)) < 0)
  268.     {
  269.         file_readonly = TRUE;
  270.         fd = open((char *)fname, O_RDONLY | O_EXTRA);   /* try to open ro */
  271.     }
  272. #endif
  273.     }
  274.  
  275.     if (fd < 0)                /* cannot open at all */
  276.     {
  277. #ifndef UNIX
  278.     int    isdir_f;
  279. #endif
  280.     msg_scroll = msg_save;
  281. #ifndef UNIX
  282.     /*
  283.      * On MSDOS and Amiga we can't open a directory, check here.
  284.      */
  285.     isdir_f = (mch_isdir(fname));
  286.     fname = sfname;            /* use short name now, for the messages */
  287.     if (isdir_f)
  288.         filemess(curbuf, fname, (char_u *)"is a directory", 0);
  289.     else
  290. #endif
  291.         if (newfile)
  292.         {
  293. #ifdef UNIX
  294.         if (perm < 0)
  295. #endif
  296.         {
  297.             check_need_swap(newfile);    /* may create swap file now */
  298.             filemess(curbuf, fname, (char_u *)"[New File]", 0);
  299. #ifdef AUTOCMD
  300.             apply_autocmds(EVENT_BUFNEWFILE, fname, fname, FALSE);
  301. #endif
  302.             /* remember the current file format */
  303.             curbuf->b_start_ffc = *curbuf->b_p_ff;
  304.             return OK;        /* a new file is not an error */
  305.         }
  306. #ifdef UNIX
  307.         else
  308.             filemess(curbuf, fname, (char_u *)"[Permission Denied]", 0);
  309. #endif
  310.         }
  311.  
  312.     return FAIL;
  313.     }
  314.  
  315.     /*
  316.      * Only set the 'ro' flag for readonly files the first time they are
  317.      * loaded.    Help files always get readonly mode
  318.      */
  319.     if ((check_readonly && file_readonly) || curbuf->b_help)
  320.     curbuf->b_p_ro = TRUE;
  321.  
  322.     if (newfile)
  323.     curbuf->b_p_eol = TRUE;
  324.  
  325.     check_need_swap(newfile);    /* may create swap file now */
  326.  
  327. #ifndef UNIX
  328.     fname = sfname;        /* replace with short name now, for the messages */
  329. #endif
  330.     ++no_wait_return;        /* don't wait for return yet */
  331.  
  332.     /*
  333.      * Set '[ mark to the line above where the lines go (line 1 if zero).
  334.      */
  335.     curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
  336.     curbuf->b_op_start.col = 0;
  337.  
  338. #ifdef AUTOCMD
  339.     {
  340.     int m = msg_scroll;
  341.     int n = msg_scrolled;
  342.     BUF *old_curbuf = curbuf;
  343.  
  344.     /*
  345.      * The file must be closed again, the autocommands may want to change
  346.      * the file before reading it.
  347.      */
  348.     if (!read_stdin)
  349.         close(fd);        /* ignore errors */
  350.  
  351.     /*
  352.      * The output from the autocommands should not overwrite anything and
  353.      * should not be overwritten: Set msg_scroll, restore its value if no
  354.      * output was done.
  355.      */
  356.     msg_scroll = TRUE;
  357.     if (filtering)
  358.         apply_autocmds(EVENT_FILTERREADPRE, NULL, fname, FALSE);
  359.     else if (read_stdin)
  360.         apply_autocmds(EVENT_STDINREADPRE, NULL, fname, FALSE);
  361.     else if (newfile)
  362.         apply_autocmds(EVENT_BUFREADPRE, NULL, fname, FALSE);
  363.     else
  364.         apply_autocmds(EVENT_FILEREADPRE, fname, fname, FALSE);
  365.     if (msg_scrolled == n)
  366.         msg_scroll = m;
  367.  
  368.     /*
  369.      * Don't allow the autocommands to change the current buffer.
  370.      * Try to re-open the file.
  371.      */
  372.     if (!read_stdin && (curbuf != old_curbuf ||
  373.               (fd = open((char *)fname, O_RDONLY | O_EXTRA)) < 0))
  374.     {
  375.         --no_wait_return;
  376.         msg_scroll = msg_save;
  377.         if (fd < 0)
  378.         EMSG("*ReadPre autocommands made the file unreadable");
  379.         else
  380.         EMSG("*ReadPre autocommands must not change current buffer");
  381.         return FAIL;
  382.     }
  383.     }
  384. #endif
  385.  
  386.     if (!recoverymode && !filtering && !read_stdin)
  387.     filemess(curbuf, fname, (char_u *)"", 0);   /* show that we are busy */
  388.  
  389.     msg_scroll = FALSE;                /* overwrite the file message */
  390.  
  391.     /*
  392.      * Set fileformat and linecnt now, before the "retry" caused by a wrong
  393.      * guess for fileformat, and after the autocommands, which may change
  394.      * them.
  395.      */
  396.     if (curbuf->b_p_bin)
  397.     fileformat = EOL_UNIX;            /* binary: use Unix format */
  398.     else if (*p_ffs == NUL)
  399.     fileformat = get_fileformat(curbuf);  /* use format from buffer */
  400.     else
  401.     fileformat = EOL_UNKNOWN;        /* detect from file */
  402.     linecnt = curbuf->b_ml.ml_line_count;
  403.  
  404. retry:
  405.     linerest = 0;
  406.     filesize = 0;
  407.     skip_count = lines_to_skip;
  408.     read_count = lines_to_read;
  409.     while (!error && !got_int)
  410.     {
  411.     /*
  412.      * We allocate as much space for the file as we can get, plus
  413.      * space for the old line plus room for one terminating NUL.
  414.      * The amount is limited by the fact that read() only can read
  415.      * upto max_unsigned characters (and other things).
  416.      */
  417. #if SIZEOF_INT <= 2
  418.     if (linerest >= 0x7ff0)
  419.     {
  420.         ++split;
  421.         *ptr = NL;            /* split line by inserting a NL */
  422.         size = 1;
  423.     }
  424.     else
  425. #endif
  426.     {
  427. #if SIZEOF_INT > 2
  428.         size = 0x10000L;            /* use buffer >= 64K */
  429. #else
  430.         size = 0x7ff0L - linerest;        /* limit buffer to 32K */
  431. #endif
  432.  
  433.         for ( ; size >= 10; size = (long_u)size >> 1)
  434.         {
  435.         if ((new_buffer = lalloc((long_u)(size + linerest + 1),
  436.                                   FALSE)) != NULL)
  437.             break;
  438.         }
  439.         if (new_buffer == NULL)
  440.         {
  441.         do_outofmem_msg();
  442.         error = TRUE;
  443.         break;
  444.         }
  445.         if (linerest)    /* copy characters from the previous buffer */
  446.         vim_memmove(new_buffer, ptr - linerest, (size_t)linerest);
  447.         vim_free(buffer);
  448.         buffer = new_buffer;
  449.         ptr = buffer + linerest;
  450.         line_start = buffer;
  451.  
  452.         if ((size = read(fd, (char *)ptr, (size_t)size)) <= 0)
  453.         {
  454.         if (size < 0)            /* read error */
  455.             error = TRUE;
  456.         break;
  457.         }
  458.         filesize += size;            /* count the number of characters */
  459.  
  460.         /*
  461.          * when reading the first part of a file: guess EOL type
  462.          */
  463.         if (fileformat == EOL_UNKNOWN)
  464.         {
  465.         /* First try finding a NL, for Dos and Unix */
  466.         if (try_dos || try_unix)
  467.         {
  468.             for (p = ptr; p < ptr + size; ++p)
  469.             if (*p == NL)
  470.             {
  471.                 if (!try_unix
  472.                     || (try_dos && p > ptr && p[-1] == CR))
  473.                 fileformat = EOL_DOS;
  474.                 else
  475.                 fileformat = EOL_UNIX;
  476.                 break;
  477.             }
  478.         }
  479.  
  480.         /* No NL found: may use Mac format */
  481.         if (fileformat == EOL_UNKNOWN && try_mac)
  482.             fileformat = EOL_MAC;
  483.  
  484.         /* Still nothing found?  Use first format in 'ffs' */
  485.         if (fileformat == EOL_UNKNOWN)
  486.             fileformat = default_fileformat();
  487.  
  488.         /* if editing a new file: may set p_tx and p_ff */
  489.         if (newfile)
  490.             set_fileformat(fileformat);
  491.         }
  492.     }
  493.  
  494.     /*
  495.      * This loop is executed once for every character read.
  496.      * Keep it fast!
  497.      */
  498.     if (fileformat == EOL_MAC)
  499.     {
  500.         --ptr;
  501.         while (++ptr, --size >= 0)
  502.         {
  503.         /* catch most common case first */
  504.         if ((c = *ptr) != NUL && c != CR && c != NL)
  505.             continue;
  506.         if (c == NUL)
  507.             *ptr = NL;    /* NULs are replaced by newlines! */
  508.         else
  509.         {
  510.             if (skip_count == 0)
  511.             {
  512.             if (c == NL)
  513.             {
  514.                 /*
  515.                  * Reading in Mac format, but a NL found!
  516.                  * When 'fileformats' includes "unix" or "dos",
  517.                  * delete all the lines read so far and start all
  518.                  * over again.  Otherwise give an error message
  519.                  * later.
  520.                  */
  521.                 if (ff_error == EOL_UNKNOWN)
  522.                 {
  523.                 if ((try_dos || try_unix)
  524.                     && !read_stdin
  525.                     && lseek(fd, (off_t)0L, SEEK_SET) == 0)
  526.                 {
  527.                     while (lnum > from)
  528.                     ml_delete(lnum--, FALSE);
  529.                     if (!try_unix || ptr[-1] == NUL)
  530.                     fileformat = EOL_DOS;
  531.                     else
  532.                     fileformat = EOL_UNIX;
  533.                     if (newfile)
  534.                     set_fileformat(fileformat);
  535.                     goto retry;
  536.                 }
  537.                 else
  538.                     ff_error = EOL_MAC;
  539.                 }
  540.             }
  541.             *ptr = NUL;        /* end of line */
  542.             len = ptr - line_start + 1;
  543.             if (ml_append(lnum, line_start, len, newfile) == FAIL)
  544.             {
  545.                 error = TRUE;
  546.                 break;
  547.             }
  548.             ++lnum;
  549.             if (--read_count == 0)
  550.             {
  551.                 error = TRUE;        /* break loop */
  552.                 line_start = ptr;    /* nothing left to write */
  553.                 break;
  554.             }
  555.             }
  556.             else
  557.             --skip_count;
  558.             line_start = ptr + 1;
  559.         }
  560.         }
  561.     }
  562.     else
  563.     {
  564.         --ptr;
  565.         while (++ptr, --size >= 0)
  566.         {
  567.         if ((c = *ptr) != NUL && c != NL)  /* catch most common case */
  568.             continue;
  569.         if (c == NUL)
  570.             *ptr = NL;    /* NULs are replaced by newlines! */
  571.         else
  572.         {
  573.             if (skip_count == 0)
  574.             {
  575.             *ptr = NUL;        /* end of line */
  576.             len = ptr - line_start + 1;
  577.             if (fileformat == EOL_DOS)
  578.             {
  579.                 if (ptr[-1] == CR)    /* remove CR */
  580.                 {
  581.                 ptr[-1] = NUL;
  582.                 --len;
  583.                 }
  584.                 /*
  585.                  * Reading in Dos format, but no CR-LF found!
  586.                  * When 'fileformats' includes "unix", delete all
  587.                  * the lines read so far and start all over again.
  588.                  * Otherwise give an error message later.
  589.                  */
  590.                 else if (ff_error != EOL_DOS)
  591.                 {
  592.                 if (       try_unix
  593.                     && !read_stdin
  594.                     && lseek(fd, (off_t)0L, SEEK_SET) == 0)
  595.                 {
  596.                     while (lnum > from)
  597.                     ml_delete(lnum--, FALSE);
  598.                     fileformat = EOL_UNIX;
  599.                     if (newfile)
  600.                     set_fileformat(EOL_UNIX);
  601.                     goto retry;
  602.                 }
  603.                 else
  604.                     ff_error = EOL_DOS;
  605.                 }
  606.             }
  607.             if (ml_append(lnum, line_start, len, newfile) == FAIL)
  608.             {
  609.                 error = TRUE;
  610.                 break;
  611.             }
  612.             ++lnum;
  613.             if (--read_count == 0)
  614.             {
  615.                 error = TRUE;        /* break loop */
  616.                 line_start = ptr;    /* nothing left to write */
  617.                 break;
  618.             }
  619.             }
  620.             else
  621.             --skip_count;
  622.             line_start = ptr + 1;
  623.         }
  624.         }
  625.     }
  626.     linerest = ptr - line_start;
  627.     ui_breakcheck();
  628.     }
  629.  
  630.     /* not an error, max. number of lines reached */
  631.     if (error && read_count == 0)
  632.     error = FALSE;
  633.  
  634.     /*
  635.      * If we get EOF in the middle of a line, note the fact and
  636.      * complete the line ourselves.
  637.      * In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
  638.      */
  639.     if (!error && !got_int && linerest != 0 &&
  640.         !(!curbuf->b_p_bin && fileformat == EOL_DOS &&
  641.             *line_start == Ctrl('Z') && ptr == line_start + 1))
  642.     {
  643.     if (newfile)            /* remember for when writing */
  644.         curbuf->b_p_eol = FALSE;
  645.     *ptr = NUL;
  646.     if (ml_append(lnum, line_start,
  647.             (colnr_t)(ptr - line_start + 1), newfile) == FAIL)
  648.         error = TRUE;
  649.     else
  650.         read_no_eol_lnum = ++lnum;
  651.     }
  652.     if (lnum != from && !newfile)   /* added at least one line */
  653.     CHANGED;
  654.  
  655.     invalidate_botline();        /* need to recompute w_botline */
  656.     changed_line_abv_curs();        /* need to recompute cursor posn */
  657.     if (newfile)
  658.     curbuf->b_start_ffc = *curbuf->b_p_ff;    /* remember 'fileformat' */
  659.  
  660.     close(fd);                /* errors are ignored */
  661.     vim_free(buffer);
  662.  
  663.     --no_wait_return;            /* may wait for return now */
  664.  
  665.     /*
  666.      * In recovery mode everything but autocommands are skipped.
  667.      */
  668.     if (!recoverymode)
  669.     {
  670.     /* need to delete the last line, which comes from the empty buffer */
  671.     if (newfile && !(curbuf->b_ml.ml_flags & ML_EMPTY))
  672.     {
  673.         ml_delete(curbuf->b_ml.ml_line_count, FALSE);
  674.         --linecnt;
  675.     }
  676.     linecnt = curbuf->b_ml.ml_line_count - linecnt;
  677.     if (filesize == 0)
  678.         linecnt = 0;
  679.     if (!newfile)
  680.         mark_adjust(from + 1, (linenr_t)MAXLNUM, (long)linecnt, 0L);
  681.  
  682.     /*
  683.      * If we were reading from the same terminal as where messages go,
  684.      * the screen will have been messed up.
  685.      * Switch on raw mode now and clear the screen.
  686.      */
  687.     if (read_stdin)
  688.     {
  689.         settmode(TMODE_RAW);        /* set to raw mode */
  690.         starttermcap();
  691.         screenclear();
  692.     }
  693.  
  694.     if (got_int)
  695.     {
  696.         filemess(curbuf, fname, e_interr, 0);
  697.         msg_scroll = msg_save;
  698. #ifdef VIMINFO
  699.         check_marks_read();
  700. #endif
  701.         return OK;        /* an interrupt isn't really an error */
  702.     }
  703.  
  704.     if (!filtering)
  705.     {
  706.         msg_add_fname(curbuf, fname);   /* fname in IObuff with quotes */
  707.         c = FALSE;
  708.  
  709. #ifdef UNIX
  710. # ifdef S_ISFIFO
  711.         if (S_ISFIFO(perm))                /* fifo or socket */
  712.         {
  713.         STRCAT(IObuff, "[fifo/socket]");
  714.         c = TRUE;
  715.         }
  716. # else
  717. #  ifdef S_IFIFO
  718.         if ((perm & S_IFMT) == S_IFIFO)        /* fifo */
  719.         {
  720.         STRCAT(IObuff, "[fifo]");
  721.         c = TRUE;
  722.         }
  723. #  endif
  724. #  ifdef S_IFSOCK
  725.         if ((perm & S_IFMT) == S_IFSOCK)        /* or socket */
  726.         {
  727.         STRCAT(IObuff, "[socket]");
  728.         c = TRUE;
  729.         }
  730. #  endif
  731. # endif
  732. #endif
  733.         if (curbuf->b_p_ro)
  734.         {
  735.         STRCAT(IObuff, shortmess(SHM_RO) ? "[RO]" : "[readonly]");
  736.         c = TRUE;
  737.         }
  738.         if (read_no_eol_lnum)
  739.         {
  740.         msg_add_eol();
  741.         c = TRUE;
  742.         }
  743.         if (ff_error == EOL_DOS)
  744.         {
  745.         STRCAT(IObuff, "[CR missing]");
  746.         c = TRUE;
  747.         }
  748.         if (ff_error == EOL_MAC)
  749.         {
  750.         STRCAT(IObuff, "[NL found]");
  751.         c = TRUE;
  752.         }
  753.         if (split)
  754.         {
  755.         STRCAT(IObuff, "[long lines split]");
  756.         c = TRUE;
  757.         }
  758.         if (error)
  759.         {
  760.         STRCAT(IObuff, "[READ ERRORS]");
  761.         c = TRUE;
  762.         }
  763.         if (msg_add_fileformat(fileformat))
  764.         c = TRUE;
  765.         msg_add_lines(c, (long)linecnt, filesize);
  766.         msg_trunc(IObuff);
  767.     }
  768.  
  769.     if (error && newfile)    /* with errors we should not write the file */
  770.         curbuf->b_p_ro = TRUE;
  771.  
  772.     u_clearline();        /* cannot use "U" command after adding lines */
  773.  
  774.     /*
  775.      * In Ex mode: cursor at last new line.
  776.      * Otherwise: cursor at first new line.
  777.      */
  778.     if (exmode_active)
  779.         curwin->w_cursor.lnum = from + linecnt;
  780.     else
  781.         curwin->w_cursor.lnum = from + 1;
  782.     check_cursor_lnum();
  783.     beginline(BL_WHITE | BL_FIX);        /* on first non-blank */
  784.  
  785.     /*
  786.      * Set '[ and '] marks to the newly read lines.
  787.      */
  788.     curbuf->b_op_start.lnum = from + 1;
  789.     curbuf->b_op_start.col = 0;
  790.     curbuf->b_op_end.lnum = from + linecnt;
  791.     curbuf->b_op_end.col = 0;
  792.     }
  793.     msg_scroll = msg_save;
  794.  
  795. #ifdef VIMINFO
  796.     /*
  797.      * Get the marks before executing autocommands, so they can be used there.
  798.      */
  799.     check_marks_read();
  800. #endif
  801.  
  802. #ifdef AUTOCMD
  803.     {
  804.     int m = msg_scroll;
  805.     int n = msg_scrolled;
  806.  
  807.     /*
  808.      * Trick: We remember if the last line of the read didn't have
  809.      * an eol for when writing it again.  This is required for
  810.      * ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
  811.      */
  812.     write_no_eol_lnum = read_no_eol_lnum;
  813.  
  814.     /*
  815.      * The output from the autocommands should not overwrite anything and
  816.      * should not be overwritten: Set msg_scroll, restore its value if no
  817.      * output was done.
  818.      */
  819.     msg_scroll = TRUE;
  820.     if (filtering)
  821.         apply_autocmds(EVENT_FILTERREADPOST, NULL, fname, FALSE);
  822.     else if (read_stdin)
  823.         apply_autocmds(EVENT_STDINREADPOST, NULL, fname, FALSE);
  824.     else if (newfile)
  825.         apply_autocmds(EVENT_BUFREADPOST, NULL, fname, FALSE);
  826.     else
  827.         apply_autocmds(EVENT_FILEREADPOST, fname, fname, FALSE);
  828.     if (msg_scrolled == n)
  829.         msg_scroll = m;
  830.     }
  831. #endif
  832.  
  833.     if (recoverymode && error)
  834.     return FAIL;
  835.     return OK;
  836. }
  837.  
  838. #ifdef VIMINFO
  839.     static void
  840. check_marks_read()
  841. {
  842.     if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0)
  843.     {
  844.     read_viminfo(NULL, FALSE, TRUE, FALSE);
  845.     curbuf->b_marks_read = TRUE;
  846.     }
  847. }
  848. #endif
  849.  
  850. #ifdef UNIX
  851.     static void
  852. set_file_time(fname, atime, mtime)
  853.     char_u  *fname;
  854.     time_t  atime;        /* access time */
  855.     time_t  mtime;        /* modification time */
  856. {
  857. # if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
  858. #  include <utime.h>
  859.  
  860.     struct utimbuf  buf;
  861.  
  862.     buf.actime    = atime;
  863.     buf.modtime    = mtime;
  864.     (void)utime((char *)fname, &buf);
  865. # else
  866. #  if defined(HAVE_UTIMES)
  867.  
  868.     struct timeval  tvp[2];
  869.  
  870.     tvp[0].tv_sec   = atime;
  871.     tvp[0].tv_usec  = 0;
  872.     tvp[1].tv_sec   = mtime;
  873.     tvp[1].tv_usec  = 0;
  874.     (void)utimes((char *)fname, &tvp);
  875. #  endif
  876. # endif
  877. }
  878. #endif /* UNIX */
  879.  
  880. /*
  881.  * buf_write() - write to file 'fname' lines 'start' through 'end'
  882.  *
  883.  * We do our own buffering here because fwrite() is so slow.
  884.  *
  885.  * If forceit is true, we don't care for errors when attempting backups (jw).
  886.  * In case of an error everything possible is done to restore the original file.
  887.  * But when forceit is TRUE, we risk loosing it.
  888.  * When reset_changed is TRUE and start == 1 and end ==
  889.  * curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
  890.  *
  891.  * This function must NOT use NameBuff (because it's called by autowrite()).
  892.  *
  893.  * return FAIL for failure, OK otherwise
  894.  */
  895.     int
  896. buf_write(buf, fname, sfname, start, end, append, forceit,
  897.                               reset_changed, filtering)
  898.     BUF            *buf;
  899.     char_u        *fname;
  900.     char_u        *sfname;
  901.     linenr_t        start, end;
  902.     int            append;
  903.     int            forceit;
  904.     int            reset_changed;
  905.     int            filtering;
  906. {
  907.     int            fd;
  908.     char_u        *backup = NULL;
  909.     char_u        *ffname;
  910. #ifdef AUTOCMD
  911.     BUF            *save_buf;
  912. #endif
  913.     char_u        *s;
  914.     char_u        *ptr;
  915.     char_u        c;
  916.     int            len;
  917.     linenr_t        lnum;
  918.     long        nchars;
  919.     char_u        *errmsg = NULL;
  920.     char_u        *buffer;
  921.     char_u        smallbuf[SMBUFSIZE];
  922.     char_u        *backup_ext;
  923.     int            bufsize;
  924.     long        perm;            /* file permissions */
  925.     int            retval = OK;
  926.     int            newfile = FALSE;        /* TRUE if file doesn't exist yet */
  927.     int            msg_save = msg_scroll;
  928.     int            overwriting;        /* TRUE if writing over original */
  929.     int            no_eol = FALSE;        /* no end-of-line written */
  930. #if defined(UNIX) || defined(__EMX__XX)        /*XXX fix me sometime? */
  931.     struct stat        st_old;
  932.     int            made_writable = FALSE;  /* 'w' bit has been set */
  933. #endif
  934. #ifdef AMIGA
  935.     BPTR        flock;
  936. #endif
  937.                         /* writing everything */
  938.     int            whole = (start == 1 && end == buf->b_ml.ml_line_count);
  939. #ifdef AUTOCMD
  940.     linenr_t        old_line_count = buf->b_ml.ml_line_count;
  941. #endif
  942.     int            attr;
  943.     int            fileformat = get_fileformat(buf);
  944.  
  945.     if (fname == NULL || *fname == NUL)        /* safety check */
  946.     return FAIL;
  947.  
  948.     /*
  949.      * If there is no file name yet, use the one for the written file.
  950.      * b_notedited is set to reflect this (in case the write fails).
  951.      * Don't do this when the write is for a filter command.
  952.      * Only do this when 'cpoptions' contains the 'f' flag.
  953.      */
  954.     if (reset_changed && whole && buf == curbuf &&
  955.                    curbuf->b_ffname == NULL && !filtering &&
  956.                     vim_strchr(p_cpo, CPO_FNAMEW) != NULL)
  957.     {
  958.     if (setfname(fname, sfname, FALSE) == OK)
  959.         curbuf->b_notedited = TRUE;
  960.     }
  961.  
  962.     if (sfname == NULL)
  963.     sfname = fname;
  964.     /*
  965.      * For Unix: Use the short file name whenever possible.
  966.      * Avoids problems with networks and when directory names are changed.
  967.      * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
  968.      * another directory, which we don't detect
  969.      */
  970.     ffname = fname;                /* remember full fname */
  971. #ifdef UNIX
  972.     fname = sfname;
  973. #endif
  974.  
  975.     /* make sure we have a valid backup extension to use */
  976.     if (*p_bex == NUL)
  977.     backup_ext = (char_u *)".bak";
  978.     else
  979.     backup_ext = p_bex;
  980.  
  981.     if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0)
  982.     overwriting = TRUE;
  983.     else
  984.     overwriting = FALSE;
  985.  
  986.     /*
  987.      * Disallow writing from .exrc and .vimrc in current directory for
  988.      * security reasons.
  989.      */
  990.     if (check_secure())
  991.     return FAIL;
  992.  
  993.     if (exiting)
  994.     settmode(TMODE_COOK);        /* when exiting allow typahead now */
  995.  
  996.     ++no_wait_return;            /* don't wait for return yet */
  997.  
  998.     /*
  999.      * Set '[ and '] marks to the lines to be written.
  1000.      */
  1001.     buf->b_op_start.lnum = start;
  1002.     buf->b_op_start.col = 0;
  1003.     buf->b_op_end.lnum = end;
  1004.     buf->b_op_end.col = 0;
  1005.  
  1006. #ifdef AUTOCMD
  1007.     /*
  1008.      * Apply PRE aucocommands.
  1009.      * Set curbuf to the buffer to be written.
  1010.      * Careful: The autocommands may call buf_write() recursively!
  1011.      */
  1012.     save_buf = curbuf;
  1013.     curbuf = buf;
  1014.     curwin->w_buffer = buf;
  1015.     if (append)
  1016.     apply_autocmds(EVENT_FILEAPPENDPRE, fname, fname, FALSE);
  1017.     else if (filtering)
  1018.     apply_autocmds(EVENT_FILTERWRITEPRE, NULL, fname, FALSE);
  1019.     else if (reset_changed && whole)
  1020.     apply_autocmds(EVENT_BUFWRITEPRE, fname, fname, FALSE);
  1021.     else
  1022.     apply_autocmds(EVENT_FILEWRITEPRE, fname, fname, FALSE);
  1023.     /*
  1024.      * If the autocommands deleted or unloaded the buffer, give an error
  1025.      * message.
  1026.      */
  1027.     if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL)
  1028.     {
  1029.     --no_wait_return;
  1030.     msg_scroll = msg_save;
  1031.     EMSG("Autocommands deleted or unloaded buffer to be written");
  1032.     return FAIL;
  1033.     }
  1034.     /*
  1035.      * If the autocommands didn't change the current buffer, go back to the
  1036.      * original current buffer, if it still exists.
  1037.      */
  1038.     if (curbuf == buf && buf_valid(save_buf))
  1039.     {
  1040.     curbuf = save_buf;
  1041.     curwin->w_buffer = save_buf;
  1042.     }
  1043.  
  1044.     /*
  1045.      * The autocommands may have changed the number of lines in the file.
  1046.      * When writing the whole file, adjust the end.
  1047.      * When writing part of the file, assume that the autocommands only
  1048.      * changed the number of lines that are to be written (tricky!).
  1049.      */
  1050.     if (buf->b_ml.ml_line_count != old_line_count)
  1051.     {
  1052.     if (whole)                        /* writing all */
  1053.         end = buf->b_ml.ml_line_count;
  1054.     else if (buf->b_ml.ml_line_count > old_line_count)  /* more lines */
  1055.         end += buf->b_ml.ml_line_count - old_line_count;
  1056.     else                            /* less lines */
  1057.     {
  1058.         end -= old_line_count - buf->b_ml.ml_line_count;
  1059.         if (end < start)
  1060.         {
  1061.         --no_wait_return;
  1062.         msg_scroll = msg_save;
  1063.         EMSG("Autocommand changed number of lines in unexpected way");
  1064.         return FAIL;
  1065.         }
  1066.     }
  1067.     }
  1068. #endif
  1069.  
  1070.     if (shortmess(SHM_OVER))
  1071.     msg_scroll = FALSE;        /* overwrite previous file message */
  1072.     else
  1073.     msg_scroll = TRUE;        /* don't overwrite previous file message */
  1074.     if (!filtering)
  1075.     filemess(buf,
  1076. #ifndef UNIX
  1077.         sfname,
  1078. #else
  1079.         fname,
  1080. #endif
  1081.             (char_u *)"", 0);    /* show that we are busy */
  1082.     msg_scroll = FALSE;            /* always overwrite the file message now */
  1083.  
  1084.     buffer = alloc(BUFSIZE);
  1085.     if (buffer == NULL)            /* can't allocate big buffer, use small
  1086.                      * one (to be able to write when out of
  1087.                      * memory) */
  1088.     {
  1089.     buffer = smallbuf;
  1090.     bufsize = SMBUFSIZE;
  1091.     }
  1092.     else
  1093.     bufsize = BUFSIZE;
  1094.  
  1095. #if defined(UNIX) && !defined(ARCHIE)
  1096.     /* get information about original file (if there is one) */
  1097.     st_old.st_dev = st_old.st_ino = 0;
  1098.     perm = -1;
  1099.     if (stat((char *)fname, &st_old))
  1100.     newfile = TRUE;
  1101.     else
  1102.     {
  1103. #ifdef _POSIX_SOURCE
  1104.     if (!S_ISREG(st_old.st_mode))        /* not a file */
  1105. #else
  1106.     if ((st_old.st_mode & S_IFMT) != S_IFREG)   /* not a file */
  1107. #endif
  1108.     {
  1109. #ifdef _POSIX_SOURCE
  1110.         if (S_ISDIR(st_old.st_mode))
  1111. #else
  1112.         if ((st_old.st_mode & S_IFMT) == S_IFDIR)
  1113. #endif
  1114.         errmsg = (char_u *)"is a directory";
  1115.         else
  1116.         errmsg = (char_u *)"is not a file";
  1117.         goto fail;
  1118.     }
  1119.     if (overwriting)
  1120.     {
  1121.         retval = check_mtime(buf, &st_old);
  1122.         if (retval == FAIL)
  1123.         goto fail;
  1124.     }
  1125.     perm = st_old.st_mode;
  1126.     }
  1127. /*
  1128.  * If we are not appending or filtering, the file exists, and the
  1129.  * 'writebackup', 'backup' or 'patchmode' option is set, try to make a backup
  1130.  * copy of the file.
  1131.  */
  1132.     if (!append && !filtering && perm >= 0 && (p_wb || p_bk || *p_pm != NUL)
  1133.         && (fd = open((char *)fname, O_RDONLY | O_EXTRA)) >= 0)
  1134.     {
  1135.     int        bfd, buflen;
  1136.     char_u        copybuf[BUFSIZE + 1], *wp;
  1137.     int        some_error = FALSE;
  1138.     struct stat    st_new;
  1139.     char_u        *dirp;
  1140.     char_u        *rootname;
  1141. #ifndef SHORT_FNAME
  1142.     int        did_set_shortname;
  1143. #endif
  1144.  
  1145.     /*
  1146.      * Try to make the backup in each directory in the 'bdir' option.
  1147.      *
  1148.      * Unix semantics has it, that we may have a writable file,
  1149.      * that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
  1150.      *  - the directory is not writable,
  1151.      *  - the file may be a symbolic link,
  1152.      *  - the file may belong to another user/group, etc.
  1153.      *
  1154.      * For these reasons, the existing writable file must be truncated
  1155.      * and reused. Creation of a backup COPY will be attempted.
  1156.      */
  1157.     dirp = p_bdir;
  1158.     while (*dirp)
  1159.     {
  1160.         st_new.st_dev = st_new.st_ino = 0;
  1161.         st_new.st_gid = 0;
  1162.  
  1163.         /*
  1164.          * Isolate one directory name, using an entry in 'bdir'.
  1165.          */
  1166.         (void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
  1167.         rootname = get_file_in_dir(fname, copybuf);
  1168.         if (rootname == NULL)
  1169.         {
  1170.         some_error = TRUE;        /* out of memory */
  1171.         goto nobackup;
  1172.         }
  1173.  
  1174.  
  1175. #ifndef SHORT_FNAME
  1176.         did_set_shortname = FALSE;
  1177. #endif
  1178.  
  1179.         /*
  1180.          * May try twice if 'shortname' not set.
  1181.          */
  1182.         for (;;)
  1183.         {
  1184.         /*
  1185.          * Make backup file name.
  1186.          */
  1187.         backup = buf_modname(
  1188. #ifdef SHORT_FNAME
  1189.                     TRUE,
  1190. #else
  1191.                     (buf->b_p_sn || buf->b_shortname),
  1192. #endif
  1193.                          rootname, backup_ext, FALSE);
  1194.         if (backup == NULL)
  1195.         {
  1196.             some_error = TRUE;        /* out of memory */
  1197.             vim_free(rootname);
  1198.             goto nobackup;
  1199.         }
  1200.  
  1201.         /*
  1202.          * Check if backup file already exists.
  1203.          */
  1204.         if (!stat((char *)backup, &st_new))
  1205.         {
  1206.             /*
  1207.              * Check if backup file is same as original file.
  1208.              * May happen when modname gave the same file back.
  1209.              * E.g. silly link, or file name-length reached.
  1210.              * If we don't check here, we either ruin the file when
  1211.              * copying or erase it after writing. jw.
  1212.              */
  1213.             if (st_new.st_dev == st_old.st_dev &&
  1214.                        st_new.st_ino == st_old.st_ino)
  1215.             {
  1216.             vim_free(backup);
  1217.             backup = NULL;    /* there is no backup file to delete */
  1218. #ifndef SHORT_FNAME
  1219.             /*
  1220.              * may try again with 'shortname' set
  1221.              */
  1222.             if (!(buf->b_shortname || buf->b_p_sn))
  1223.             {
  1224.                 buf->b_shortname = TRUE;
  1225.                 did_set_shortname = TRUE;
  1226.                 continue;
  1227.             }
  1228.                 /* setting shortname didn't help */
  1229.             if (did_set_shortname)
  1230.                 buf->b_shortname = FALSE;
  1231. #endif
  1232.             break;
  1233.             }
  1234.  
  1235.             /*
  1236.              * If we are not going to keep the backup file, don't
  1237.              * delete an existing one, try to use another name.
  1238.              * Change one character, just before the extension.
  1239.              */
  1240.             if (!p_bk)
  1241.             {
  1242.             wp = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
  1243.             if (wp < backup)    /* empty file name ??? */
  1244.                 wp = backup;
  1245.             *wp = 'z';
  1246.             while (*wp > 'a' && !stat((char *)backup, &st_new))
  1247.                 --*wp;
  1248.             /* They all exist??? Must be something wrong. */
  1249.             if (*wp == 'a')
  1250.             {
  1251.                 vim_free(backup);
  1252.                 backup = NULL;
  1253.             }
  1254.             }
  1255.         }
  1256.         break;
  1257.         }
  1258.         vim_free(rootname);
  1259.  
  1260.         /*
  1261.          * Try to create the backup file
  1262.          */
  1263.         if (backup != NULL)
  1264.         {
  1265.         /* remove old backup, if present */
  1266.         vim_remove(backup);
  1267.         bfd = open((char *)backup, O_WRONLY | O_CREAT | O_EXTRA, 0666);
  1268.         if (bfd < 0)
  1269.         {
  1270.             vim_free(backup);
  1271.             backup = NULL;
  1272.         }
  1273.         else
  1274.         {
  1275.             /* set file protection same as original file, but strip
  1276.              * s-bit */
  1277.             (void)mch_setperm(backup, perm & 0777);
  1278.  
  1279.             /*
  1280.              * Try to set the group of the backup same as the original
  1281.              * file. If this fails, set the protection bits for the
  1282.              * group same as the protection bits for others.
  1283.              */
  1284.             if (st_new.st_gid != st_old.st_gid &&
  1285. #ifdef HAVE_FCHOWN  /* sequent-ptx lacks fchown() */
  1286.                     fchown(bfd, (uid_t)-1, st_old.st_gid) != 0
  1287. #else
  1288.               chown((char *)backup, (uid_t)-1, st_old.st_gid) != 0
  1289. #endif
  1290.                         )
  1291.             mch_setperm(backup, (perm & 0707) | ((perm & 07) << 3));
  1292.  
  1293.             /* copy the file. */
  1294.             while ((buflen = read(fd, (char *)copybuf, BUFSIZE)) > 0)
  1295.             {
  1296.             if (write_buf(bfd, copybuf, buflen) == FAIL)
  1297.             {
  1298.                 errmsg = (char_u *)"Can't write to backup file (use ! to override)";
  1299.                 break;
  1300.             }
  1301.             }
  1302.             if (close(bfd) < 0 && errmsg == NULL)
  1303.             errmsg = (char_u *)"Close error for backup file (use ! to override)";
  1304.             if (buflen < 0)
  1305.             errmsg = (char_u *)"Can't read file for backup (use ! to override)";
  1306.             set_file_time(backup, st_old.st_atime, st_old.st_mtime);
  1307.             break;
  1308.         }
  1309.         }
  1310.     }
  1311. nobackup:
  1312.     close(fd);        /* ignore errors for closing read file */
  1313.  
  1314.     if (backup == NULL && errmsg == NULL)
  1315.         errmsg = (char_u *)"Cannot create backup file (use ! to override)";
  1316.     /* ignore errors when forceit is TRUE */
  1317.     if ((some_error || errmsg) && !forceit)
  1318.     {
  1319.         retval = FAIL;
  1320.         goto fail;
  1321.     }
  1322.     errmsg = NULL;
  1323.     }
  1324.     /* When using ":w!" and the file was read-only: make it writable */
  1325.     if (forceit && st_old.st_uid == getuid() && perm >= 0 && !(perm & 0200)
  1326.                      && vim_strchr(p_cpo, CPO_FWRITE) == NULL)
  1327.     {
  1328.     perm |= 0200;
  1329.     (void)mch_setperm(fname, perm);
  1330.     made_writable = TRUE;
  1331.     }
  1332.  
  1333. #else /* end of UNIX, start of the rest */
  1334.  
  1335. /*
  1336.  * If we are not appending, the file exists, and the 'writebackup' or
  1337.  * 'backup' option is set, make a backup.
  1338.  * Do not make any backup, if "writebackup" and "backup" are
  1339.  * both switched off. This helps when editing large files on
  1340.  * almost-full disks. (jw)
  1341.  */
  1342.     perm = mch_getperm(fname);
  1343.     if (perm < 0)
  1344.     newfile = TRUE;
  1345.     else if (mch_isdir(fname))
  1346.     {
  1347.     errmsg = (char_u *)"is a directory";
  1348.     goto fail;
  1349.     }
  1350.     else if (overwriting)
  1351.     {
  1352.     struct stat    st;
  1353.  
  1354.     if (stat((char *)fname, &st) >= 0)
  1355.     {
  1356.         retval = check_mtime(buf, &st);
  1357.         if (retval == FAIL)
  1358.         goto fail;
  1359.     }
  1360.     }
  1361.  
  1362.     if (!append && !filtering && perm >= 0 && (p_wb || p_bk || *p_pm != NUL))
  1363.     {
  1364.     char_u        *dirp;
  1365.     char_u        *p;
  1366.     char_u        *rootname;
  1367.  
  1368.     /*
  1369.      * Form the backup file name - change path/fo.o.h to path/fo.o.h.bak
  1370.      * Try all directories in 'backupdir', first one that works is used.
  1371.      */
  1372.     dirp = p_bdir;
  1373.     while (*dirp)
  1374.     {
  1375.         /*
  1376.          * Isolate one directory name and make the backup file name.
  1377.          */
  1378.         (void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
  1379.         rootname = get_file_in_dir(fname, IObuff);
  1380.         if (rootname == NULL)
  1381.         backup = NULL;
  1382.         else
  1383.         {
  1384.         backup = buf_modname(
  1385. #ifdef SHORT_FNAME
  1386.                     TRUE,
  1387. #else
  1388.                     (buf->b_p_sn || buf->b_shortname),
  1389. #endif
  1390.                          rootname, backup_ext, FALSE);
  1391.         vim_free(rootname);
  1392.         }
  1393.  
  1394.         if (backup != NULL)
  1395.         {
  1396.         /*
  1397.          * If we are not going to keep the backup file, don't
  1398.          * delete an existing one, try to use another name.
  1399.          * Change one character, just before the extension.
  1400.          */
  1401.         if (!p_bk && mch_getperm(backup) >= 0)
  1402.         {
  1403.             p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
  1404.             if (p < backup)    /* empty file name ??? */
  1405.             p = backup;
  1406.             *p = 'z';
  1407.             while (*p > 'a' && mch_getperm(backup) >= 0)
  1408.             --*p;
  1409.             /* They all exist??? Must be something wrong! */
  1410.             if (*p == 'a')
  1411.             {
  1412.             vim_free(backup);
  1413.             backup = NULL;
  1414.             }
  1415.         }
  1416.         }
  1417.         if (backup != NULL)
  1418.         {
  1419.  
  1420.         /*
  1421.          * Delete any existing backup and move the current version to
  1422.          * the backup.    For safety, we don't remove the backup until
  1423.          * the write has finished successfully. And if the 'backup'
  1424.          * option is set, leave it around.
  1425.          */
  1426. #ifdef AMIGA
  1427.         /*
  1428.          * With MSDOS-compatible filesystems (crossdos, messydos) it is
  1429.          * possible that the name of the backup file is the same as the
  1430.          * original file. To avoid the chance of accidently deleting the
  1431.          * original file (horror!) we lock it during the remove.
  1432.          * This should not happen with ":w", because startscript()
  1433.          * should detect this problem and set buf->b_shortname,
  1434.          * causing modname to return a correct ".bak" file name. This
  1435.          * problem does exist with ":w file name", but then the
  1436.          * original file will be somewhere else so the backup isn't
  1437.          * really important. If autoscripting is off the rename may
  1438.          * fail.
  1439.          */
  1440.         flock = Lock((UBYTE *)fname, (long)ACCESS_READ);
  1441. #endif
  1442.         vim_remove(backup);
  1443. #ifdef AMIGA
  1444.         if (flock)
  1445.             UnLock(flock);
  1446. #endif
  1447.         /*
  1448.          * If the renaming of the original file to the backup file
  1449.          * works, quit here.
  1450.          */
  1451.         if (vim_rename(fname, backup) == 0)
  1452.             break;
  1453.  
  1454.         vim_free(backup);   /* don't do the rename below */
  1455.         backup = NULL;
  1456.         }
  1457.     }
  1458.     if (backup == NULL && !forceit)
  1459.     {
  1460.         errmsg = (char_u *)"Can't make backup file (use ! to override)";
  1461.         goto fail;
  1462.     }
  1463.     }
  1464. #endif /* UNIX */
  1465.  
  1466.     /* When using ":w!" and writing to the current file, readonly makes no
  1467.      * sense, reset it */
  1468.     if (forceit && overwriting)
  1469.     buf->b_p_ro = FALSE;
  1470.  
  1471.     /*
  1472.      * If the original file is being overwritten, there is a small chance that
  1473.      * we crash in the middle of writing. Therefore the file is preserved now.
  1474.      * This makes all block numbers positive so that recovery does not need
  1475.      * the original file.
  1476.      * Don't do this if there is a backup file and we are exiting.
  1477.      */
  1478.     if (reset_changed && !newfile && !otherfile(ffname) &&
  1479.                         !(exiting && backup != NULL))
  1480.     ml_preserve(buf, FALSE);
  1481.  
  1482.     /*
  1483.      * We may try to open the file twice: If we can't write to the
  1484.      * file and forceit is TRUE we delete the existing file and try to create
  1485.      * a new one. If this still fails we may have lost the original file!
  1486.      * (this may happen when the user reached his quotum for number of files).
  1487.      * Appending will fail if the file does not exist and forceit is FALSE.
  1488.      */
  1489.     while ((fd = open((char *)fname, O_WRONLY | O_EXTRA | (append ?
  1490.             (forceit ? (O_APPEND | O_CREAT) : O_APPEND) :
  1491.             (O_CREAT | O_TRUNC))
  1492. #ifndef macintosh
  1493.             , 0666
  1494. #endif
  1495.                 )) < 0)
  1496.     {
  1497.     /*
  1498.      * A forced write will try to create a new file if the old one is
  1499.      * still readonly. This may also happen when the directory is
  1500.      * read-only. In that case the vim_remove() will fail.
  1501.      */
  1502.     if (!errmsg)
  1503.     {
  1504.         errmsg = (char_u *)"Can't open file for writing";
  1505.         if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL)
  1506.         {
  1507. #ifdef UNIX
  1508.         /* we write to the file, thus it should be marked
  1509.                             writable after all */
  1510.         if (!(perm & 0200))
  1511.             made_writable = TRUE;
  1512.         perm |= 0200;
  1513.         if (st_old.st_uid != getuid() || st_old.st_gid != getgid())
  1514.             perm &= 0777;
  1515. #endif
  1516.         if (!append)        /* don't remove when appending */
  1517.             vim_remove(fname);
  1518.         continue;
  1519.         }
  1520.     }
  1521. /*
  1522.  * If we failed to open the file, we don't need a backup. Throw it away.
  1523.  * If we moved or removed the original file try to put the backup in its place.
  1524.  */
  1525.     if (backup != NULL)
  1526.     {
  1527. #ifdef UNIX
  1528.         struct stat st;
  1529.  
  1530.         /*
  1531.          * There is a small chance that we removed the original, try
  1532.          * to move the copy in its place.
  1533.          * This may not work if the vim_rename() fails.
  1534.          * In that case we leave the copy around.
  1535.          */
  1536.                     /* file does not exist */
  1537.         if (stat((char *)fname, &st) < 0)
  1538.                     /* put the copy in its place */
  1539.         vim_rename(backup, fname);
  1540.                     /* original file does exist */
  1541.         if (stat((char *)fname, &st) >= 0)
  1542.         vim_remove(backup); /* throw away the copy */
  1543. #else
  1544.                     /* try to put the original file back */
  1545.         vim_rename(backup, fname);
  1546. #endif
  1547.     }
  1548.     goto fail;
  1549.     }
  1550.     errmsg = NULL;
  1551.  
  1552.     if (end > buf->b_ml.ml_line_count)
  1553.     end = buf->b_ml.ml_line_count;
  1554.     len = 0;
  1555.     s = buffer;
  1556.     nchars = 0;
  1557.     if (buf->b_ml.ml_flags & ML_EMPTY)
  1558.     start = end + 1;
  1559.     for (lnum = start; lnum <= end; ++lnum)
  1560.     {
  1561.     /*
  1562.      * The next while loop is done once for each character written.
  1563.      * Keep it fast!
  1564.      */
  1565.     ptr = ml_get_buf(buf, lnum, FALSE) - 1;
  1566.     while ((c = *++ptr) != NUL)
  1567.     {
  1568.         if (c == NL)
  1569.         *s = NUL;        /* replace newlines with NULs */
  1570.         else
  1571.         *s = c;
  1572.         ++s;
  1573.         if (++len != bufsize)
  1574.         continue;
  1575.         if (write_buf(fd, buffer, bufsize) == FAIL)
  1576.         {
  1577.         end = 0;        /* write error: break loop */
  1578.         break;
  1579.         }
  1580.         nchars += bufsize;
  1581.         s = buffer;
  1582.         len = 0;
  1583.     }
  1584.     /* write failed or last line has no EOL: stop here */
  1585.     if (end == 0 || (lnum == end && buf->b_p_bin &&
  1586.                         (lnum == write_no_eol_lnum ||
  1587.              (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol))))
  1588.     {
  1589.         ++lnum;            /* written the line, count it */
  1590.         no_eol = TRUE;
  1591.         break;
  1592.     }
  1593.     if (fileformat == EOL_UNIX)
  1594.         *s++ = NL;
  1595.     else
  1596.     {
  1597.         *s++ = CR;            /* EOL_MAC or EOL_DOS: write CR */
  1598.         if (fileformat == EOL_DOS)    /* write CR-NL */
  1599.         {
  1600.         if (++len == bufsize)
  1601.         {
  1602.             if (write_buf(fd, buffer, bufsize) == FAIL)
  1603.             {
  1604.             end = 0;    /* write error: break loop */
  1605.             break;
  1606.             }
  1607.             nchars += bufsize;
  1608.             s = buffer;
  1609.             len = 0;
  1610.         }
  1611.         *s++ = NL;
  1612.         }
  1613.     }
  1614.     if (++len == bufsize && end)
  1615.     {
  1616.         if (write_buf(fd, buffer, bufsize) == FAIL)
  1617.         {
  1618.         end = 0;        /* write error: break loop */
  1619.         break;
  1620.         }
  1621.         nchars += bufsize;
  1622.         s = buffer;
  1623.         len = 0;
  1624.     }
  1625.     }
  1626.     if (len && end)
  1627.     {
  1628.     if (write_buf(fd, buffer, len) == FAIL)
  1629.         end = 0;            /* write error */
  1630.     nchars += len;
  1631.     }
  1632.  
  1633.     if (close(fd) != 0)
  1634.     {
  1635.     errmsg = (char_u *)"Close failed";
  1636.     goto fail;
  1637.     }
  1638. #ifdef UNIX
  1639.     if (made_writable)
  1640.     perm &= ~0200;        /* reset 'w' bit for security reasons */
  1641. #endif
  1642.     if (perm >= 0)        /* set perm. of new file same as old file */
  1643.     (void)mch_setperm(fname, perm);
  1644.  
  1645.     if (end == 0)
  1646.     {
  1647.     errmsg = (char_u *)"write error (file system full?)";
  1648.     /*
  1649.      * If we have a backup file, try to put it in place of the new file,
  1650.      * because it is probably corrupt. This avoids loosing the original
  1651.      * file when trying to make a backup when writing the file a second
  1652.      * time.
  1653.      * For unix this means copying the backup over the new file.
  1654.      * For others this means renaming the backup file.
  1655.      * If this is OK, don't give the extra warning message.
  1656.      */
  1657.     if (backup != NULL)
  1658.     {
  1659. #ifdef UNIX
  1660.         char_u    copybuf[BUFSIZE + 1];
  1661.         int        bfd, buflen;
  1662.  
  1663.         if ((bfd = open((char *)backup, O_RDONLY | O_EXTRA)) >= 0)
  1664.         {
  1665.         if ((fd = open((char *)fname,
  1666.               O_WRONLY | O_CREAT | O_TRUNC | O_EXTRA, 0666 )) >= 0)
  1667.         {
  1668.             /* copy the file. */
  1669.             while ((buflen = read(bfd, (char *)copybuf, BUFSIZE)) > 0)
  1670.             if (write_buf(fd, copybuf, buflen) == FAIL)
  1671.                 break;
  1672.             if (close(fd) >= 0 && buflen == 0)    /* success */
  1673.             end = 1;
  1674.         }
  1675.         close(bfd);    /* ignore errors for closing read file */
  1676.         }
  1677. #else
  1678.         if (vim_rename(backup, fname) == 0)
  1679.         end = 1;
  1680. #endif
  1681.     }
  1682.     goto fail;
  1683.     }
  1684.  
  1685.     lnum -= start;        /* compute number of written lines */
  1686.     --no_wait_return;        /* may wait for return now */
  1687.  
  1688. #ifndef UNIX
  1689.     fname = sfname;        /* use shortname now, for the messages */
  1690. #endif
  1691.     if (!filtering)
  1692.     {
  1693.     msg_add_fname(buf, fname);    /* put fname in IObuff with quotes */
  1694.     c = FALSE;
  1695.     if (newfile)
  1696.     {
  1697.         STRCAT(IObuff, shortmess(SHM_NEW) ? "[New]" : "[New File]");
  1698.         c = TRUE;
  1699.     }
  1700.     if (no_eol)
  1701.     {
  1702.         msg_add_eol();
  1703.         c = TRUE;
  1704.     }
  1705.     /* may add [unix/dos/mac] */
  1706.     if (msg_add_fileformat(fileformat))
  1707.         c = TRUE;
  1708.     msg_add_lines(c, (long)lnum, nchars);    /* add line/char count */
  1709.     if (!shortmess(SHM_WRITE))
  1710.         STRCAT(IObuff, shortmess(SHM_WRI) ? " [w]" : " written");
  1711.  
  1712.     keep_msg = msg_trunc(IObuff);
  1713.     keep_msg_attr = 0;
  1714.     }
  1715.  
  1716.     if (reset_changed && whole)        /* when written everything */
  1717.     {
  1718.     UNCHANGED(buf);
  1719.     if (buf->b_start_ffc != *buf->b_p_ff)
  1720.     {
  1721.         buf->b_start_ffc = *buf->b_p_ff;    /* keep this fileformat */
  1722.         check_status(buf);
  1723.     }
  1724.     u_unchanged(buf);
  1725.     }
  1726.  
  1727.     /*
  1728.      * If written to the current file, update the timestamp of the swap file
  1729.      * and reset the 'notedited' flag. Also sets buf->b_mtime.
  1730.      */
  1731.     if (!exiting && overwriting)
  1732.     {
  1733.     ml_timestamp(buf);
  1734.     buf->b_notedited = FALSE;
  1735.     }
  1736.  
  1737.     /*
  1738.      * If we kept a backup until now, and we are in patch mode, then we make
  1739.      * the backup file our 'original' file.
  1740.      */
  1741.     if (*p_pm)
  1742.     {
  1743.     char *org = (char *)buf_modname(
  1744. #ifdef SHORT_FNAME
  1745.                     TRUE,
  1746. #else
  1747.                     (buf->b_p_sn || buf->b_shortname),
  1748. #endif
  1749.                               fname, p_pm, FALSE);
  1750.  
  1751.     if (backup != NULL)
  1752.     {
  1753.         struct stat st;
  1754.  
  1755.         /*
  1756.          * If the original file does not exist yet
  1757.          * the current backup file becomes the original file
  1758.          */
  1759.         if (org == NULL)
  1760.         EMSG("patchmode: can't save original file");
  1761.         else if (stat(org, &st) < 0)
  1762.         {
  1763.         vim_rename(backup, (char_u *)org);
  1764.         vim_free(backup);        /* don't delete the file */
  1765.         backup = NULL;
  1766. #ifdef UNIX
  1767.         set_file_time((char_u *)org, st_old.st_atime, st_old.st_mtime);
  1768. #endif
  1769.         }
  1770.     }
  1771.     /*
  1772.      * If there is no backup file, remember that a (new) file was
  1773.      * created.
  1774.      */
  1775.     else
  1776.     {
  1777.         int empty_fd;
  1778.  
  1779.         if (org == NULL || (empty_fd = open(org, O_CREAT | O_EXTRA
  1780. #ifndef macintosh
  1781.                 , 0666
  1782. #endif
  1783.                     )) < 0)
  1784.           EMSG("patchmode: can't touch empty original file");
  1785.         else
  1786.           close(empty_fd);
  1787.     }
  1788.     if (org != NULL)
  1789.     {
  1790.         mch_setperm((char_u *)org, mch_getperm(fname) & 0777);
  1791.         vim_free(org);
  1792.     }
  1793.     }
  1794.  
  1795.     /*
  1796.      * Remove the backup unless 'backup' option is set
  1797.      */
  1798.     if (!p_bk && backup != NULL && vim_remove(backup) != 0)
  1799.     EMSG("Can't delete backup file");
  1800.  
  1801.     goto nofail;
  1802.  
  1803. fail:
  1804.     --no_wait_return;        /* may wait for return now */
  1805. nofail:
  1806.  
  1807.     vim_free(backup);
  1808.     if (buffer != smallbuf)
  1809.     vim_free(buffer);
  1810.  
  1811.     if (errmsg != NULL)
  1812.     {
  1813.     attr = highlight_attr[HLF_E];    /* set highlight for error messages */
  1814.     msg_add_fname(buf,
  1815. #ifndef UNIX
  1816.         sfname
  1817. #else
  1818.         fname
  1819. #endif
  1820.              );            /* put file name in IObuff with quotes */
  1821.     STRCAT(IObuff, errmsg);
  1822.     emsg(IObuff);
  1823.  
  1824.     retval = FAIL;
  1825.     if (end == 0)
  1826.     {
  1827.         MSG_PUTS_ATTR("\nWARNING: Original file may be lost or damaged\n",
  1828.             attr);
  1829.         MSG_PUTS_ATTR("don't quit the editor until the file is successfully written!",
  1830.             attr);
  1831.     }
  1832.     }
  1833.     msg_scroll = msg_save;
  1834.  
  1835. #ifdef AUTOCMD
  1836.     write_no_eol_lnum = 0;    /* in case it was set by the previous read */
  1837.  
  1838.     /*
  1839.      * Apply POST autocommands.
  1840.      * Careful: The autocommands may call buf_write() recursively!
  1841.      */
  1842.     save_buf = curbuf;
  1843.     curbuf = buf;
  1844.     curwin->w_buffer = buf;
  1845.     if (append)
  1846.     apply_autocmds(EVENT_FILEAPPENDPOST, fname, fname, FALSE);
  1847.     else if (filtering)
  1848.     apply_autocmds(EVENT_FILTERWRITEPOST, NULL, fname, FALSE);
  1849.     else if (reset_changed && whole)
  1850.     apply_autocmds(EVENT_BUFWRITEPOST, fname, fname, FALSE);
  1851.     else
  1852.     apply_autocmds(EVENT_FILEWRITEPOST, fname, fname, FALSE);
  1853.     /*
  1854.      * If the autocommands didn't change the current buffer, go back to the
  1855.      * original current buffer, if it still exists.
  1856.      */
  1857.     if (curbuf == buf && buf_valid(save_buf))
  1858.     {
  1859.     curbuf = save_buf;
  1860.     curwin->w_buffer = save_buf;
  1861.     }
  1862. #endif
  1863.  
  1864.     return retval;
  1865. }
  1866.  
  1867. /*
  1868.  * Put file name into IObuff with quotes.
  1869.  */
  1870.     static void
  1871. msg_add_fname(buf, fname)
  1872.     BUF        *buf;
  1873.     char_u  *fname;
  1874. {
  1875.     if (fname == NULL)
  1876.     fname = (char_u *)"-stdin-";
  1877.     home_replace(buf, fname, IObuff + 1, IOSIZE - 1);
  1878.     IObuff[0] = '"';
  1879.     STRCAT(IObuff, "\" ");
  1880. }
  1881.  
  1882. /*
  1883.  * Append message for text mode to IObuff.
  1884.  * Return TRUE if something appended.
  1885.  */
  1886.     static int
  1887. msg_add_fileformat(eol_type)
  1888.     int        eol_type;
  1889. {
  1890. #ifndef USE_CRNL
  1891.     if (eol_type == EOL_DOS)
  1892.     {
  1893.     STRCAT(IObuff, shortmess(SHM_TEXT) ? "[dos]" : "[dos format]");
  1894.     return TRUE;
  1895.     }
  1896. #endif
  1897. #ifndef USE_CR
  1898.     if (eol_type == EOL_MAC)
  1899.     {
  1900.     STRCAT(IObuff, shortmess(SHM_TEXT) ? "[mac]" : "[mac format]");
  1901.     return TRUE;
  1902.     }
  1903. #endif
  1904. #if defined(USE_CRNL) || defined(USE_CR)
  1905.     if (eol_type == EOL_UNIX)
  1906.     {
  1907.     STRCAT(IObuff, shortmess(SHM_TEXT) ? "[unix]" : "[unix format]");
  1908.     return TRUE;
  1909.     }
  1910. #endif
  1911.     return FALSE;
  1912. }
  1913.  
  1914. /*
  1915.  * Append line and character count to IObuff.
  1916.  */
  1917.     static void
  1918. msg_add_lines(insert_space, lnum, nchars)
  1919.     int        insert_space;
  1920.     long    lnum;
  1921.     long    nchars;
  1922. {
  1923.     char_u  *p;
  1924.  
  1925.     p = IObuff + STRLEN(IObuff);
  1926.  
  1927.     if (insert_space)
  1928.     *p++ = ' ';
  1929.     if (shortmess(SHM_LINES))
  1930.     sprintf((char *)p, "%ldL, %ldC", lnum, nchars);
  1931.     else
  1932.     sprintf((char *)p, "%ld line%s, %ld character%s",
  1933.         lnum, plural(lnum),
  1934.         nchars, plural(nchars));
  1935. }
  1936.  
  1937. /*
  1938.  * Append message for missing line separator to IObuff.
  1939.  */
  1940.     static void
  1941. msg_add_eol()
  1942. {
  1943.     STRCAT(IObuff, shortmess(SHM_LAST) ? "[noeol]" : "[Incomplete last line]");
  1944. }
  1945.  
  1946. /*
  1947.  * Check modification time of file, before writing to it.
  1948.  */
  1949.     static int
  1950. check_mtime(buf, st)
  1951.     BUF            *buf;
  1952.     struct stat        *st;
  1953. {
  1954.     if (buf->b_mtime_read != 0
  1955. #ifdef __linux__
  1956.         /* In Linux, on a FAT filesystem, there are only 5 bits to store
  1957.          * the seconds.  Since the roundoff is done when flushing the
  1958.          * inode, the time may change unexpectedly by one second!!! */
  1959.         && st->st_mtime - buf->b_mtime_read > 1
  1960. #else
  1961.         && buf->b_mtime_read != st->st_mtime
  1962. #endif
  1963.         )
  1964.     {
  1965.     msg_scroll = TRUE;        /* don't overwrite messages here */
  1966.     /* don't use emsg() here, don't want to flush the buffers */
  1967.     MSG_ATTR("WARNING: The file has been changed since reading it!!!",
  1968.                                highlight_attr[HLF_E]);
  1969.     if (ask_yesno((char_u *)"Do you really want to write to it",
  1970.                                  TRUE) == 'n')
  1971.         return FAIL;
  1972.     msg_scroll = FALSE;        /* always overwrite the file message now */
  1973.     }
  1974.     return OK;
  1975. }
  1976.  
  1977. /*
  1978.  * write_buf: call write() to write a buffer
  1979.  *
  1980.  * return FAIL for failure, OK otherwise
  1981.  */
  1982.     static int
  1983. write_buf(fd, buf, len)
  1984.     int        fd;
  1985.     char_u  *buf;
  1986.     int        len;
  1987. {
  1988.     int        wlen;
  1989.  
  1990.     while (len)
  1991.     {
  1992.     wlen = write(fd, (char *)buf, (size_t)len);
  1993.     if (wlen <= 0)            /* error! */
  1994.         return FAIL;
  1995.     len -= wlen;
  1996.     buf += wlen;
  1997.     }
  1998.     return OK;
  1999. }
  2000.  
  2001. /*
  2002.  * shorten_fname: Try to find a shortname by comparing the fullname with the
  2003.  * current directory.
  2004.  * Returns NULL if not shorter name possible, pointer into "full_path"
  2005.  * otherwise.
  2006.  */
  2007.     char_u *
  2008. shorten_fname(full_path, dir_name)
  2009.     char_u  *full_path;
  2010.     char_u  *dir_name;
  2011. {
  2012.     int            len;
  2013.     char_u        *p;
  2014.  
  2015.     if (full_path == NULL)
  2016.     return NULL;
  2017.     len = STRLEN(dir_name);
  2018.     if (fnamencmp(dir_name, full_path, len) == 0)
  2019.     {
  2020.     p = full_path + len;
  2021.     if (vim_ispathsep(*p))
  2022.         ++p;
  2023.     else
  2024.         p = NULL;
  2025.     }
  2026.     else
  2027.     p = NULL;
  2028.     return p;
  2029. }
  2030.  
  2031. /*
  2032.  * add extention to file name - change path/fo.o.h to path/fo.o.h.ext or
  2033.  * fo_o_h.ext for MSDOS or when shortname option set.
  2034.  *
  2035.  * Assumed that fname is a valid name found in the filesystem we assure that
  2036.  * the return value is a different name and ends in 'ext'.
  2037.  * "ext" MUST be at most 4 characters long if it starts with a dot, 3
  2038.  * characters otherwise.
  2039.  * Space for the returned name is allocated, must be freed later.
  2040.  * Returns NULL when out of memory.
  2041.  */
  2042.     char_u *
  2043. modname(fname, ext, prepend_dot)
  2044.     char_u *fname, *ext;
  2045.     int        prepend_dot;    /* may prepend a '.' to file name */
  2046. {
  2047.     return buf_modname(
  2048. #ifdef SHORT_FNAME
  2049.             TRUE,
  2050. #else
  2051.             (curbuf->b_p_sn || curbuf->b_shortname),
  2052. #endif
  2053.                              fname, ext, prepend_dot);
  2054. }
  2055.  
  2056.     char_u *
  2057. buf_modname(shortname, fname, ext, prepend_dot)
  2058.     int        shortname;        /* use 8.3 file name */
  2059.     char_u  *fname, *ext;
  2060.     int        prepend_dot;    /* may prepend a '.' to file name (for Unix) */
  2061. {
  2062.     char_u    *retval;
  2063.     char_u    *s;
  2064.     char_u    *e;
  2065.     char_u    *ptr;
  2066.     int        fnamelen, extlen;
  2067.  
  2068.     extlen = STRLEN(ext);
  2069.  
  2070.     /*
  2071.      * If there is no file name we must get the name of the current directory
  2072.      * (we need the full path in case :cd is used).
  2073.      */
  2074.     if (fname == NULL || *fname == NUL)
  2075.     {
  2076.     retval = alloc((unsigned)(MAXPATHL + extlen + 3));
  2077.     if (retval == NULL)
  2078.         return NULL;
  2079.     if (mch_dirname(retval, MAXPATHL) == FAIL ||
  2080.                          (fnamelen = STRLEN(retval)) == 0)
  2081.     {
  2082.         vim_free(retval);
  2083.         return NULL;
  2084.     }
  2085.     if (!vim_ispathsep(retval[fnamelen - 1]))
  2086.     {
  2087.         retval[fnamelen++] = PATHSEP;
  2088.         retval[fnamelen] = NUL;
  2089.     }
  2090. #ifndef SHORT_FNAME
  2091.     prepend_dot = FALSE;        /* nothing to prepend a dot to */
  2092. #endif
  2093.     }
  2094.     else
  2095.     {
  2096.     fnamelen = STRLEN(fname);
  2097.     retval = alloc((unsigned)(fnamelen + extlen + 3));
  2098.     if (retval == NULL)
  2099.         return NULL;
  2100.     STRCPY(retval, fname);
  2101.     }
  2102.  
  2103.     /*
  2104.      * search backwards until we hit a '/', '\' or ':' replacing all '.'
  2105.      * by '_' for MSDOS or when shortname option set and ext starts with a dot.
  2106.      * Then truncate what is after the '/', '\' or ':' to 8 characters for
  2107.      * MSDOS and 26 characters for AMIGA, a lot more for UNIX.
  2108.      */
  2109.     for (ptr = retval + fnamelen; ptr >= retval; ptr--)
  2110.     {
  2111.     if (*ext == '.'
  2112. #ifdef USE_LONG_FNAME
  2113.             && (!USE_LONG_FNAME || shortname)
  2114. #else
  2115. # ifndef SHORT_FNAME
  2116.             && shortname
  2117. # endif
  2118. #endif
  2119.                                 )
  2120.         if (*ptr == '.')    /* replace '.' by '_' */
  2121.         *ptr = '_';
  2122.     if (vim_ispathsep(*ptr))
  2123.         break;
  2124.     }
  2125.     ptr++;
  2126.  
  2127.     /* the file name has at most BASENAMELEN characters. */
  2128. #ifndef SHORT_FNAME
  2129.     if (STRLEN(ptr) > (unsigned)BASENAMELEN)
  2130.     ptr[BASENAMELEN] = '\0';
  2131. #endif
  2132.  
  2133.     s = ptr + STRLEN(ptr);
  2134.  
  2135.     /*
  2136.      * For 8.3 file names we may have to reduce the length.
  2137.      */
  2138. #ifdef USE_LONG_FNAME
  2139.     if (!USE_LONG_FNAME || shortname)
  2140. #else
  2141. # ifndef SHORT_FNAME
  2142.     if (shortname)
  2143. # endif
  2144. #endif
  2145.     {
  2146.     /*
  2147.      * If there is no file name, and the extension starts with '.', put a
  2148.      * '_' before the dot, because just ".ext" is invalid.
  2149.      */
  2150.     if (fname == NULL || *fname == NUL)
  2151.     {
  2152.         if (*ext == '.')
  2153.         *s++ = '_';
  2154.     }
  2155.     /*
  2156.      * If the extension starts with '.', truncate the base name at 8
  2157.      * characters
  2158.      */
  2159.     else if (*ext == '.')
  2160.     {
  2161.         if (s - ptr > (size_t)8)
  2162.         {
  2163.         s = ptr + 8;
  2164.         *s = '\0';
  2165.         }
  2166.     }
  2167.     /*
  2168.      * If the extension doesn't start with '.', and the file name
  2169.      * doesn't have an extension yet, append a '.'
  2170.      */
  2171.     else if ((e = vim_strchr(ptr, '.')) == NULL)
  2172.         *s++ = '.';
  2173.     /*
  2174.      * If If the extension doesn't start with '.', and there already is an
  2175.      * extension, it may need to be tructated
  2176.      */
  2177.     else if ((int)STRLEN(e) + extlen > 4)
  2178.         s = e + 4 - extlen;
  2179.     }
  2180. #if defined(OS2) || defined(USE_LONG_FNAME) || defined(WIN32)
  2181.     /*
  2182.      * If there is no file name, and the extension starts with '.', put a
  2183.      * '_' before the dot, because just ".ext" may be invalid if it's on a
  2184.      * FAT partition, and on HPFS it doesn't matter.
  2185.      */
  2186.     else if ((fname == NULL || *fname == NUL) && *ext == '.')
  2187.     *s++ = '_';
  2188. #endif
  2189.  
  2190.     /*
  2191.      * Append the extention.
  2192.      * ext can start with '.' and cannot exceed 3 more characters.
  2193.      */
  2194.     STRCPY(s, ext);
  2195.  
  2196. #ifndef SHORT_FNAME
  2197.     /*
  2198.      * Prepend the dot.
  2199.      */
  2200.     if (prepend_dot && !shortname && *(e = gettail(retval)) != '.'
  2201. #ifdef USE_LONG_FNAME
  2202.         && USE_LONG_FNAME
  2203. #endif
  2204.                 )
  2205.     {
  2206.     vim_memmove(e + 1, e, STRLEN(e) + 1);
  2207.     *e = '.';
  2208.     }
  2209. #endif
  2210.  
  2211.     /*
  2212.      * Check that, after appending the extension, the file name is really
  2213.      * different.
  2214.      */
  2215.     if (fname != NULL && STRCMP(fname, retval) == 0)
  2216.     {
  2217.     /* we search for a character that can be replaced by '_' */
  2218.     while (--s >= ptr)
  2219.     {
  2220.         if (*s != '_')
  2221.         {
  2222.         *s = '_';
  2223.         break;
  2224.         }
  2225.     }
  2226.     if (s < ptr)    /* fname was "________.<ext>" how tricky! */
  2227.         *ptr = 'v';
  2228.     }
  2229.     return retval;
  2230. }
  2231.  
  2232. /* vim_fgets();
  2233.  *
  2234.  * Like fgets(), but if the file line is too long, it is truncated and the
  2235.  * rest of the line is thrown away.  Returns TRUE for end-of-file.
  2236.  * Note: do not pass IObuff as the buffer since this is used to read and
  2237.  * discard the extra part of any long lines.
  2238.  */
  2239.     int
  2240. vim_fgets(buf, size, fp)
  2241.     char_u    *buf;
  2242.     int        size;
  2243.     FILE    *fp;
  2244. {
  2245.     char *eof;
  2246.  
  2247.     buf[size - 2] = NUL;
  2248.     eof = fgets((char *)buf, size, fp);
  2249.     if (buf[size - 2] != NUL && buf[size - 2] != '\n')
  2250.     {
  2251.     buf[size - 1] = NUL;        /* Truncate the line */
  2252.  
  2253.     /* Now throw away the rest of the line: */
  2254.     do
  2255.     {
  2256.         IObuff[IOSIZE - 2] = NUL;
  2257.         fgets((char *)IObuff, IOSIZE, fp);
  2258.     } while (IObuff[IOSIZE - 2] != NUL && IObuff[IOSIZE - 2] != '\n');
  2259.     }
  2260.     return (eof == NULL);
  2261. }
  2262.  
  2263. /*
  2264.  * rename() only works if both files are on the same file system, this
  2265.  * function will (attempts to?) copy the file across if rename fails -- webb
  2266.  * Return -1 for failure, 0 for success.
  2267.  */
  2268.     int
  2269. vim_rename(from, to)
  2270.     char_u *from;
  2271.     char_u *to;
  2272. {
  2273.     int        fd_in;
  2274.     int        fd_out;
  2275.     int        n;
  2276.     char    *errmsg = NULL;
  2277.     char    *buffer;
  2278.  
  2279.     /*
  2280.      * First delete the "to" file, this is required on some systems to make
  2281.      * the rename() work, on other systems it makes sure that we don't have
  2282.      * two files when the rename() fails.
  2283.      */
  2284.     vim_remove(to);
  2285.  
  2286.     /*
  2287.      * First try a normal rename, return if it works.
  2288.      */
  2289.     if (rename((char *)from, (char *)to) == 0)
  2290.     return 0;
  2291.  
  2292.     /*
  2293.      * Rename() failed, try copying the file.
  2294.      */
  2295.     fd_in = open((char *)from, O_RDONLY | O_EXTRA);
  2296.     if (fd_in == -1)
  2297.     return -1;
  2298.     fd_out = open((char *)to, O_CREAT | O_TRUNC | O_WRONLY | O_EXTRA
  2299. #ifndef macintosh
  2300.             , 0666
  2301. #endif
  2302.             );
  2303.     if (fd_out == -1)
  2304.     {
  2305.     close(fd_in);
  2306.     return -1;
  2307.     }
  2308.  
  2309.     buffer = (char *)alloc(BUFSIZE);
  2310.     if (buffer == NULL)
  2311.     {
  2312.     close(fd_in);
  2313.     close(fd_out);
  2314.     return -1;
  2315.     }
  2316.  
  2317.     while ((n = read(fd_in, buffer, (size_t)BUFSIZE)) > 0)
  2318.     if (write(fd_out, buffer, (size_t)n) != n)
  2319.     {
  2320.         errmsg = "writing to";
  2321.         break;
  2322.     }
  2323.  
  2324.     vim_free(buffer);
  2325.     close(fd_in);
  2326.     if (close(fd_out) < 0)
  2327.     errmsg = "closing";
  2328.     if (n < 0)
  2329.     {
  2330.     errmsg = "reading";
  2331.     to = from;
  2332.     }
  2333.     if (errmsg != NULL)
  2334.     {
  2335.     sprintf((char *)IObuff, "Error %s '%s'", errmsg, to);
  2336.     emsg(IObuff);
  2337.     return -1;
  2338.     }
  2339.     vim_remove(from);
  2340.     return 0;
  2341. }
  2342.  
  2343. /*
  2344.  * Check if any not hidden buffer has been changed.
  2345.  * Postpone the check if there are characters in the stuff buffer, a global
  2346.  * command is being executed, a mapping is being executed or an autocommand is
  2347.  * busy.
  2348.  */
  2349.     void
  2350. check_timestamps()
  2351. {
  2352.     BUF        *buf;
  2353.  
  2354.     if (!stuff_empty() || global_busy || !typebuf_typed()
  2355. #ifdef AUTOCMD
  2356.             || autocmd_busy
  2357. #endif
  2358.                     )
  2359.     need_check_timestamps = TRUE;        /* check later */
  2360.     else
  2361.     {
  2362.     ++no_wait_return;
  2363.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  2364.         buf_check_timestamp(buf);
  2365.     --no_wait_return;
  2366.     need_check_timestamps = FALSE;
  2367.     }
  2368. }
  2369.  
  2370. /*
  2371.  * Check if buffer "buf" has been changed.
  2372.  */
  2373.     void
  2374. buf_check_timestamp(buf)
  2375.     BUF        *buf;
  2376. {
  2377.     struct stat        st;
  2378.     char_u        *path;
  2379.  
  2380.     if (    buf->b_ffname != NULL
  2381.         && buf->b_ml.ml_mfp != NULL
  2382.         && !buf->b_notedited
  2383.         && buf->b_mtime != 0
  2384.         && stat((char *)buf->b_ffname, &st) >= 0
  2385. #ifdef __linux__
  2386.         /* In Linux, on a FAT filesystem, there are only 5 bits to
  2387.          * store the seconds.  Since the roundoff is done when
  2388.          * flushing the inode, the time may change unexpectedly by one
  2389.          * second!!! */
  2390.         && st.st_mtime - buf->b_mtime > 1
  2391. #else
  2392.         && buf->b_mtime != st.st_mtime
  2393. #endif
  2394.         )
  2395.     {
  2396. #ifdef AUTOCMD
  2397.     /*
  2398.      * Only give the warning if there are no FileChangedShell autocommands.
  2399.      */
  2400.     if (!apply_autocmds(EVENT_FILECHANGEDSHELL, NULL, NULL, FALSE))
  2401. #endif
  2402.     {
  2403.         path = home_replace_save(buf, buf->b_fname);
  2404.         if (path != NULL)
  2405.         {
  2406.         EMSG2("Warning: File \"%s\" has changed since editing started",
  2407.                                     path);
  2408.         vim_free(path);
  2409.         }
  2410.     }
  2411.     buf->b_mtime = st.st_mtime;
  2412.     }
  2413. }
  2414.  
  2415. /*
  2416.  * Adjust the line with missing eol, used for the next write.
  2417.  * Used for do_filter(), when the input lines for the filter are deleted.
  2418.  */
  2419.     void
  2420. write_lnum_adjust(offset)
  2421.     linenr_t    offset;
  2422. {
  2423.     if (write_no_eol_lnum)        /* only if there is a missing eol */
  2424.     write_no_eol_lnum += offset;
  2425. }
  2426.  
  2427. /*
  2428.  * vim_tempname(): Return a unique name that can be used for a temp file.
  2429.  *
  2430.  * The temp file is NOT created.
  2431.  *
  2432.  * The returned pointer is to allocated memory.
  2433.  * The returned pointer is NULL if no valid name was found.
  2434.  */
  2435.     char_u  *
  2436. vim_tempname(extra_char)
  2437.     int        extra_char;        /* character to use in the name instead of '?' */
  2438. {
  2439. #ifdef USE_GUI_WIN32
  2440. # undef USE_TMPNAM
  2441. # define TEMPNAMELEN 256
  2442.     char    szTempFile[_MAX_PATH+1];
  2443. #endif
  2444. #ifdef USE_TMPNAM
  2445.     char_u    itmp[L_tmpnam];    /* use tmpnam() */
  2446. #else
  2447.     char_u    itmp[TEMPNAMELEN];
  2448. #endif
  2449. #if defined(TEMPDIRNAMES) || (!defined(USE_GUI_WIN32) && !defined(USE_TMPNAM))
  2450.     char_u        *p;
  2451. #endif
  2452.  
  2453. #ifdef TEMPDIRNAMES
  2454.     static char    *(tempdirs[]) = {TEMPDIRNAMES};
  2455.     static int    first_dir = 0;
  2456.     int        first_try = TRUE;
  2457.     int        i;
  2458.  
  2459.     /*
  2460.      * Try a few places to put the temp file.
  2461.      * To avoid waisting time with non-existing environment variables and
  2462.      * directories, they are skipped next time.
  2463.      */
  2464.     for (i = first_dir; i < sizeof(tempdirs) / sizeof(char *); ++i)
  2465.     {
  2466.     /* expand $TMP, leave room for '/', "v?XXXXXX" and NUL */
  2467.     expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 10);
  2468.     if (mch_isdir(itmp))        /* directory exists */
  2469.     {
  2470.         if (first_try)
  2471.         first_dir = i;        /* start here next time */
  2472.         first_try = FALSE;
  2473. #ifdef __EMX__
  2474.         /*
  2475.          * if $TMP contains a forward slash (perhaps because we're using
  2476.          * bash or tcsh, right Stefan?), don't add a backslash to the
  2477.          * directory before tacking on the file name; use a forward slash!
  2478.          * I first tried adding 2 backslashes, but somehow that didn't
  2479.          * work (something in the EMX system() ate them, I think).
  2480.          */
  2481.         if (vim_strchr(itmp, '/'))
  2482.         STRCAT(itmp, "/");
  2483.         else
  2484. #endif
  2485.         STRCAT(itmp, PATHSEPSTR);
  2486.         STRCAT(itmp, TEMPNAME);
  2487.         if ((p = vim_strchr(itmp, '?')) != NULL)
  2488.         *p = extra_char;
  2489.         if (*mktemp((char *)itmp) == NUL)
  2490.         continue;
  2491.         return vim_strsave(itmp);
  2492.     }
  2493.     }
  2494.     return NULL;
  2495. #else /* !TEMPDIRNAMES */
  2496.  
  2497. # ifdef USE_GUI_WIN32
  2498.     STRCPY(itmp, "");
  2499.     GetTempPath(_MAX_PATH, szTempFile);
  2500.     if (GetTempFileName(szTempFile, "VIM", 0, itmp) == 0)
  2501. # else
  2502. #  ifdef USE_TMPNAM
  2503.     /* tmpnam() will make its own name */
  2504.     if (*tmpnam((char *)itmp) == NUL)
  2505. #  else
  2506.     STRCPY(itmp, TEMPNAME);
  2507.     if ((p = vim_strchr(itmp, '?')) != NULL)
  2508.     *p = extra_char;
  2509.     if (*mktemp((char *)itmp) == NUL)
  2510. #  endif
  2511. # endif
  2512.     return NULL;
  2513. # ifdef WIN32
  2514.     {
  2515.     char_u    *p;
  2516.     char_u    *retval;
  2517.  
  2518.     /* backslashes in a temp file name cause problems when filtering with
  2519.      * "sh" */
  2520.     retval = vim_strsave(itmp);
  2521.     if (*p_shcf == '-')
  2522.         for (p = retval; *p; ++p)
  2523.         if (*p == '\\')
  2524.             *p = '/';
  2525.     return retval;
  2526.     }
  2527. # else
  2528.     return vim_strsave(itmp);
  2529. # endif
  2530. #endif /* !TEMPDIRNAMES */
  2531. }
  2532.  
  2533. /*
  2534.  * Code for automatic commands.
  2535.  *
  2536.  * Only included when "AUTOCMD" has been defined.
  2537.  */
  2538.  
  2539. #ifdef AUTOCMD
  2540.  
  2541. /*
  2542.  * The autocommands are stored in a list for each event.
  2543.  * Autocommands for the same pattern, that are consecutive, are joined
  2544.  * together, to avoid having to match the pattern too often.
  2545.  * The result is an array of Autopat lists, which point to AutoCmd lists:
  2546.  *
  2547.  * first_autopat[0] --> Autopat.next  -->  Autopat.next -->  NULL
  2548.  *            Autopat.cmds       Autopat.cmds
  2549.  *                |             |
  2550.  *                V             V
  2551.  *            AutoCmd.next       AutoCmd.next
  2552.  *                |             |
  2553.  *                V             V
  2554.  *            AutoCmd.next        NULL
  2555.  *                |
  2556.  *                V
  2557.  *               NULL
  2558.  *
  2559.  * first_autopat[1] --> Autopat.next  -->  NULL
  2560.  *            Autopat.cmds
  2561.  *                |
  2562.  *                V
  2563.  *            AutoCmd.next
  2564.  *                |
  2565.  *                V
  2566.  *               NULL
  2567.  *   etc.
  2568.  *
  2569.  *   The order of AutoCmds is important, this is the order in which they were
  2570.  *   defined and will have to be executed.
  2571.  */
  2572. typedef struct AutoCmd
  2573. {
  2574.     char_u        *cmd;        /* The command to be executed (NULL
  2575.                        when command has been removed) */
  2576.     char        nested;        /* If autocommands nest here */
  2577.     char        last;        /* last command in list */
  2578.     struct AutoCmd  *next;        /* Next AutoCmd in list */
  2579. } AutoCmd;
  2580.  
  2581. typedef struct AutoPat
  2582. {
  2583.     int            group;        /* group ID */
  2584.     char_u        *pat;        /* pattern as typed (NULL when pattern
  2585.                        has been removed) */
  2586.     char_u        *reg_pat;        /* pattern converted to regexp */
  2587.     char        allow_dirs;        /* Pattern may match whole path */
  2588.     char        last;        /* last pattern for apply_autocmds() */
  2589.     AutoCmd        *cmds;        /* list of commands to do */
  2590.     struct AutoPat  *next;        /* next AutoPat in AutoPat list */
  2591. } AutoPat;
  2592.  
  2593. static struct event_name
  2594. {
  2595.     char    *name;        /* event name */
  2596.     EVENT_T    event;        /* event number */
  2597. } event_names[] =
  2598. {
  2599.     {"BufDelete",    EVENT_BUFDELETE},
  2600.     {"BufEnter",    EVENT_BUFENTER},
  2601.     {"BufLeave",    EVENT_BUFLEAVE},
  2602.     {"BufNewFile",    EVENT_BUFNEWFILE},
  2603.     {"BufReadPost",    EVENT_BUFREADPOST},
  2604.     {"BufReadPre",    EVENT_BUFREADPRE},
  2605.     {"BufRead",        EVENT_BUFREADPOST},
  2606.     {"BufUnload",    EVENT_BUFUNLOAD},
  2607.     {"BufWritePost",    EVENT_BUFWRITEPOST},
  2608.     {"BufWritePre",    EVENT_BUFWRITEPRE},
  2609.     {"BufWrite",    EVENT_BUFWRITEPRE},
  2610.     {"FileAppendPost",    EVENT_FILEAPPENDPOST},
  2611.     {"FileAppendPre",    EVENT_FILEAPPENDPRE},
  2612.     {"FileChangedShell",    EVENT_FILECHANGEDSHELL},
  2613.     {"FileReadPost",    EVENT_FILEREADPOST},
  2614.     {"FileReadPre",    EVENT_FILEREADPRE},
  2615.     {"FileWritePost",    EVENT_FILEWRITEPOST},
  2616.     {"FileWritePre",    EVENT_FILEWRITEPRE},
  2617.     {"FilterReadPost",    EVENT_FILTERREADPOST},
  2618.     {"FilterReadPre",    EVENT_FILTERREADPRE},
  2619.     {"FilterWritePost",    EVENT_FILTERWRITEPOST},
  2620.     {"FilterWritePre",    EVENT_FILTERWRITEPRE},
  2621.     {"StdinReadPost",    EVENT_STDINREADPOST},
  2622.     {"StdinReadPre",    EVENT_STDINREADPRE},
  2623.     {"TermChanged",    EVENT_TERMCHANGED},
  2624.     {"User",        EVENT_USER},
  2625.     {"VimEnter",    EVENT_VIMENTER},
  2626.     {"VimLeave",    EVENT_VIMLEAVE},
  2627.     {"WinEnter",    EVENT_WINENTER},
  2628.     {"WinLeave",    EVENT_WINLEAVE},
  2629.     {NULL,        0}
  2630. };
  2631.  
  2632. static AutoPat *first_autopat[NUM_EVENTS] =
  2633. {
  2634.     NULL, NULL, NULL, NULL, NULL,
  2635.     NULL, NULL, NULL, NULL, NULL,
  2636.     NULL, NULL, NULL, NULL, NULL,
  2637.     NULL, NULL, NULL, NULL, NULL,
  2638.     NULL
  2639. };
  2640.  
  2641. /*
  2642.  * struct used to keep status while executing autocommands for an event.
  2643.  */
  2644. typedef struct AutoPatCmd
  2645. {
  2646.     AutoPat    *curpat;    /* next AutoPat to examine */
  2647.     AutoCmd    *nextcmd;    /* next AutoCmd to execute */
  2648.     int        group;        /* group being used */
  2649.     char_u    *fname;        /* fname to match with */
  2650.     char_u    *sfname;    /* sfname to match with */
  2651.     char_u    *tail;        /* tail of fname */
  2652.     EVENT_T    event;        /* current event */
  2653. } AutoPatCmd;
  2654.  
  2655. /*
  2656.  * augroups stores a list of autocmd group names.
  2657.  */
  2658. struct growarray augroups = {0, 0, sizeof(char_u *), 10, NULL};
  2659. #define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
  2660.  
  2661. /*
  2662.  * The ID of the current group.  Group 0 is the default one.
  2663.  */
  2664. #define AUGROUP_DEFAULT        -1        /* default autocmd group */
  2665. #define AUGROUP_ERROR        -2        /* errornouse autocmd group */
  2666. #define AUGROUP_ALL        -3        /* all autocmd groups */
  2667. static int current_augroup = AUGROUP_DEFAULT;
  2668.  
  2669. static int au_need_clean = FALSE;   /* need to delete marked patterns */
  2670.  
  2671. static void show_autocmd __ARGS((AutoPat *ap, EVENT_T event));
  2672. static void au_remove_pat __ARGS((AutoPat *ap));
  2673. static void au_remove_cmds __ARGS((AutoPat *ap));
  2674. static void au_cleanup __ARGS((void));
  2675. static int au_find_group __ARGS((char_u *name));
  2676. static int au_new_group __ARGS((char_u *name));
  2677. static int au_find_group __ARGS((char_u *name));
  2678. static EVENT_T event_name2nr __ARGS((char_u *start, char_u **end));
  2679. static char_u *event_nr2name __ARGS((EVENT_T event));
  2680. static char_u *find_end_event __ARGS((char_u *arg));
  2681. static int event_ignored __ARGS((EVENT_T event));
  2682. static int au_get_grouparg __ARGS((char_u **argp));
  2683. static int do_autocmd_event __ARGS((EVENT_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group));
  2684. static int apply_autocmds_group __ARGS((EVENT_T event, char_u *fname,
  2685.                      char_u *fname_io, int force, int group));
  2686. static char_u *getnextac __ARGS((int c, void *cookie, int indent));
  2687. static void auto_next_pat __ARGS((AutoPatCmd *apc, int stop_at_last));
  2688.  
  2689. static EVENT_T    last_event;
  2690. static int    last_group;
  2691.  
  2692. /*
  2693.  * Show the autocommands for one AutoPat.
  2694.  */
  2695.     static void
  2696. show_autocmd(ap, event)
  2697.     AutoPat    *ap;
  2698.     EVENT_T    event;
  2699. {
  2700.     AutoCmd *ac;
  2701.  
  2702.     if (got_int)            /* "q" hit for "--more--" */
  2703.     return;
  2704.     if (ap->pat == NULL)        /* pattern has been removed */
  2705.     return;
  2706.  
  2707.     msg_putchar('\n');
  2708.     if (got_int)            /* "q" hit for "--more--" */
  2709.     return;
  2710.     if (event != last_event || ap->group != last_group)
  2711.     {
  2712.     if (ap->group != AUGROUP_DEFAULT)
  2713.     {
  2714.         msg_puts_attr(AUGROUP_NAME(ap->group), highlight_attr[HLF_T]);
  2715.         msg_puts((char_u *)"  ");
  2716.     }
  2717.     msg_puts_attr(event_nr2name(event), highlight_attr[HLF_T]);
  2718.     last_event = event;
  2719.     last_group = ap->group;
  2720.     msg_putchar('\n');
  2721.     if (got_int)            /* "q" hit for "--more--" */
  2722.         return;
  2723.     }
  2724.     msg_col = 4;
  2725.     msg_outtrans(ap->pat);
  2726.  
  2727.     for (ac = ap->cmds; ac != NULL; ac = ac->next)
  2728.     {
  2729.     if (ac->cmd != NULL)        /* skip removed commands */
  2730.     {
  2731.         if (msg_col >= 14)
  2732.         msg_putchar('\n');
  2733.         msg_col = 14;
  2734.         if (got_int)        /* "q" hit for "--more--" */
  2735.         return;
  2736.         msg_outtrans(ac->cmd);
  2737.         if (got_int)        /* "q" hit for "--more--" */
  2738.         return;
  2739.         if (ac->next != NULL)
  2740.         {
  2741.         msg_putchar('\n');
  2742.         if (got_int)        /* "q" hit for "--more--" */
  2743.             return;
  2744.         }
  2745.     }
  2746.     }
  2747. }
  2748.  
  2749. /*
  2750.  * Mark an autocommand pattern for deletion.
  2751.  */
  2752.     static void
  2753. au_remove_pat(ap)
  2754.     AutoPat *ap;
  2755. {
  2756.     vim_free(ap->pat);
  2757.     ap->pat = NULL;
  2758.     au_need_clean = TRUE;
  2759. }
  2760.  
  2761. /*
  2762.  * Mark all commands for a pattern for deletion.
  2763.  */
  2764.     static void
  2765. au_remove_cmds(ap)
  2766.     AutoPat *ap;
  2767. {
  2768.     AutoCmd *ac;
  2769.  
  2770.     for (ac = ap->cmds; ac != NULL; ac = ac->next)
  2771.     {
  2772.     vim_free(ac->cmd);
  2773.     ac->cmd = NULL;
  2774.     }
  2775.     au_need_clean = TRUE;
  2776. }
  2777.  
  2778. /*
  2779.  * Cleanup autocommands and patterns that have been deleted.
  2780.  * This is only done when not executing autocommands.
  2781.  */
  2782.     static void
  2783. au_cleanup()
  2784. {
  2785.     AutoPat    *ap, **prev_ap;
  2786.     AutoCmd    *ac, **prev_ac;
  2787.     EVENT_T    event;
  2788.  
  2789.     if (autocmd_busy || !au_need_clean)
  2790.     return;
  2791.  
  2792.     /* loop over all events */
  2793.     for (event = (EVENT_T)0; event < NUM_EVENTS;
  2794.                         event = (EVENT_T)((int)event + 1))
  2795.     {
  2796.     /* loop over all autocommand patterns */
  2797.     prev_ap = &(first_autopat[event]);
  2798.     for (ap = *prev_ap; ap != NULL; ap = *prev_ap)
  2799.     {
  2800.         /* loop over all commands for this pattern */
  2801.         prev_ac = &(ap->cmds);
  2802.         for (ac = *prev_ac; ac != NULL; ac = *prev_ac)
  2803.         {
  2804.         /* remove the command if the pattern is to be deleted or when
  2805.          * the command has been marked for deletion */
  2806.         if (ap->pat == NULL || ac->cmd == NULL)
  2807.         {
  2808.             *prev_ac = ac->next;
  2809.             vim_free(ac->cmd);
  2810.             vim_free(ac);
  2811.         }
  2812.         else
  2813.             prev_ac = &(ac->next);
  2814.         }
  2815.  
  2816.         /* remove the pattern if it has been marked for deletion */
  2817.         if (ap->pat == NULL)
  2818.         {
  2819.         *prev_ap = ap->next;
  2820.         vim_free(ap->reg_pat);
  2821.         vim_free(ap);
  2822.         }
  2823.         else
  2824.         prev_ap = &(ap->next);
  2825.     }
  2826.     }
  2827.  
  2828.     au_need_clean = FALSE;
  2829. }
  2830.  
  2831. /*
  2832.  * Add an autocmd group name.
  2833.  * Return it's ID.  Returns AUGROUP_ERROR for error.
  2834.  */
  2835.     static int
  2836. au_new_group(name)
  2837.     char_u    *name;
  2838. {
  2839.     int        i;
  2840.  
  2841.     i = au_find_group(name);
  2842.     if (i == AUGROUP_ERROR)    /* the group doesn't exist yet, add it */
  2843.     {
  2844.     if (ga_grow(&augroups, 1) == FAIL)
  2845.         return AUGROUP_ERROR;
  2846.     i = augroups.ga_len;
  2847.     AUGROUP_NAME(i) = vim_strsave(name);
  2848.     if (AUGROUP_NAME(i) == NULL)
  2849.         return AUGROUP_ERROR;
  2850.     ++augroups.ga_len;
  2851.     --augroups.ga_room;
  2852.     }
  2853.  
  2854.     return i;
  2855. }
  2856.  
  2857. /*
  2858.  * Find the ID of an autocmd group name.
  2859.  * Return it's ID.  Returns AUGROUP_ERROR for error.
  2860.  */
  2861.     static int
  2862. au_find_group(name)
  2863.     char_u    *name;
  2864. {
  2865.     int        i;
  2866.  
  2867.     for (i = 0; i < augroups.ga_len; ++i)
  2868.     {
  2869.     if (AUGROUP_NAME(i) != NULL && STRCMP(AUGROUP_NAME(i), name) == 0)
  2870.         return i;
  2871.     }
  2872.     return AUGROUP_ERROR;
  2873. }
  2874.  
  2875. /*
  2876.  * Implementation of the ":augroup name" command.
  2877.  */
  2878.     void
  2879. do_augroup(arg)
  2880.     char_u    *arg;
  2881. {
  2882.     int        i;
  2883.  
  2884.     if (STRICMP(arg, "end") == 0)   /* ":aug end": back to group 0 */
  2885.     current_augroup = AUGROUP_DEFAULT;
  2886.     else if (*arg)            /* ":aug xxx": switch to group xxx */
  2887.     {
  2888.     i = au_new_group(arg);
  2889.     if (i != AUGROUP_ERROR)
  2890.         current_augroup = i;
  2891.     }
  2892.     else                /* ":aug": list the group names */
  2893.     {
  2894.     msg_start();
  2895.     for (i = 0; i < augroups.ga_len; ++i)
  2896.     {
  2897.         if (AUGROUP_NAME(i) != NULL)
  2898.         {
  2899.         msg_puts(AUGROUP_NAME(i));
  2900.         msg_puts((char_u *)"  ");
  2901.         }
  2902.     }
  2903.     msg_clr_eos();
  2904.     msg_end();
  2905.     }
  2906. }
  2907.  
  2908. /*
  2909.  * Function given to ExpandGeneric() to obtain the list of autocommand group
  2910.  * names.
  2911.  */
  2912.     char_u *
  2913. get_augroup_name(idx)
  2914.     int        idx;
  2915. {
  2916.     if (idx == augroups.ga_len)        /* add "END" add the end */
  2917.     return (char_u *)"END";
  2918.     if (idx >= augroups.ga_len)        /* end of list */
  2919.     return NULL;
  2920.     if (AUGROUP_NAME(idx) == NULL)    /* skip deleted entries */
  2921.     return (char_u *)"";
  2922.     return AUGROUP_NAME(idx);        /* return a name */
  2923. }
  2924.  
  2925. /*
  2926.  * Return the event number for event name "start".
  2927.  * Return NUM_EVENTS if the event name was not found.
  2928.  * Return a pointer to the next event name in "end".
  2929.  */
  2930.     static EVENT_T
  2931. event_name2nr(start, end)
  2932.     char_u  *start;
  2933.     char_u  **end;
  2934. {
  2935.     char_u    *p;
  2936.     int        i;
  2937.     int        len;
  2938.  
  2939.     /* the event name ends with end of line, a blank or a comma */
  2940.     for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p)
  2941.     ;
  2942.     for (i = 0; event_names[i].name != NULL; ++i)
  2943.     {
  2944.     len = strlen(event_names[i].name);
  2945.     if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
  2946.         break;
  2947.     }
  2948.     if (*p == ',')
  2949.     ++p;
  2950.     *end = p;
  2951.     if (event_names[i].name == NULL)
  2952.     return NUM_EVENTS;
  2953.     return event_names[i].event;
  2954. }
  2955.  
  2956. /*
  2957.  * Return the name for event "event".
  2958.  */
  2959.     static char_u *
  2960. event_nr2name(event)
  2961.     EVENT_T    event;
  2962. {
  2963.     int        i;
  2964.  
  2965.     for (i = 0; event_names[i].name != NULL; ++i)
  2966.     if (event_names[i].event == event)
  2967.         return (char_u *)event_names[i].name;
  2968.     return (char_u *)"Unknown";
  2969. }
  2970.  
  2971. /*
  2972.  * Scan over the events.  "*" stands for all events.
  2973.  */
  2974.     static char_u *
  2975. find_end_event(arg)
  2976.     char_u  *arg;
  2977. {
  2978.     char_u  *pat;
  2979.     char_u  *p;
  2980.  
  2981.     if (*arg == '*')
  2982.     {
  2983.     if (arg[1] && !vim_iswhite(arg[1]))
  2984.     {
  2985.         EMSG2("Illegal character after *: %s", arg);
  2986.         return NULL;
  2987.     }
  2988.     pat = arg + 1;
  2989.     }
  2990.     else
  2991.     {
  2992.     for (pat = arg; *pat && !vim_iswhite(*pat); pat = p)
  2993.     {
  2994.         if (event_name2nr(pat, &p) >= NUM_EVENTS)
  2995.         {
  2996.         EMSG2("No such event: %s", pat);
  2997.         return NULL;
  2998.         }
  2999.     }
  3000.     }
  3001.     return pat;
  3002. }
  3003.  
  3004. /*
  3005.  * Return TRUE if "event" is included in 'eventignore'.
  3006.  */
  3007.     static int
  3008. event_ignored(event)
  3009.     EVENT_T    event;
  3010. {
  3011.     char_u    *p = p_ei;
  3012.  
  3013.     if (STRICMP(p_ei, "all") == 0)
  3014.     return TRUE;
  3015.  
  3016.     while (*p)
  3017.     if (event_name2nr(p, &p) == event)
  3018.         return TRUE;
  3019.  
  3020.     return FALSE;
  3021. }
  3022.  
  3023. /*
  3024.  * Return OK when the contents of p_ei is valid, FAIL otherwise.
  3025.  */
  3026.     int
  3027. check_ei()
  3028. {
  3029.     char_u    *p = p_ei;
  3030.  
  3031.     if (STRICMP(p_ei, "all") == 0)
  3032.     return OK;
  3033.  
  3034.     while (*p)
  3035.     if (event_name2nr(p, &p) == NUM_EVENTS)
  3036.         return FAIL;
  3037.  
  3038.     return OK;
  3039. }
  3040.  
  3041. /*
  3042.  * do_autocmd() -- implements the :autocmd command.  Can be used in the
  3043.  *  following ways:
  3044.  *
  3045.  * :autocmd <event> <pat> <cmd>        Add <cmd> to the list of commands that
  3046.  *                    will be automatically executed for <event>
  3047.  *                    when editing a file matching <pat>, in
  3048.  *                    the current group.
  3049.  * :autocmd <event> <pat>        Show the auto-commands associated with
  3050.  *                    <event> and <pat>.
  3051.  * :autocmd <event>            Show the auto-commands associated with
  3052.  *                    <event>.
  3053.  * :autocmd                Show all auto-commands.
  3054.  * :autocmd! <event> <pat> <cmd>    Remove all auto-commands associated with
  3055.  *                    <event> and <pat>, and add the command
  3056.  *                    <cmd>, for the current group.
  3057.  * :autocmd! <event> <pat>        Remove all auto-commands associated with
  3058.  *                    <event> and <pat> for the current group.
  3059.  * :autocmd! <event>            Remove all auto-commands associated with
  3060.  *                    <event> for the current group.
  3061.  * :autocmd!                Remove ALL auto-commands for the current
  3062.  *                    group.
  3063.  *
  3064.  *  Multiple events and patterns may be given separated by commas.  Here are
  3065.  *  some examples:
  3066.  * :autocmd bufread,bufenter *.c,*.h    set tw=0 smartindent noic
  3067.  * :autocmd bufleave         *        set tw=79 nosmartindent ic infercase
  3068.  *
  3069.  * :autocmd * *.c        show all autocommands for *.c files.
  3070.  */
  3071.     void
  3072. do_autocmd(arg, forceit)
  3073.     char_u  *arg;
  3074.     int        forceit;
  3075. {
  3076.     char_u    *pat;
  3077.     char_u    *cmd;
  3078.     EVENT_T    event;
  3079.     int        need_free = FALSE;
  3080.     int        nested = FALSE;
  3081.     int        group;
  3082.  
  3083.     /*
  3084.      * Check for a legal group name.  If not, use AUGROUP_ALL.
  3085.      */
  3086.     group = au_get_grouparg(&arg);
  3087.     if (arg == NULL)        /* out of memory */
  3088.     return;
  3089.  
  3090.     /*
  3091.      * Scan over the events.
  3092.      * If we find an illegal name, return here, don't do anything.
  3093.      */
  3094.     pat = find_end_event(arg);
  3095.     if (pat == NULL)
  3096.     return;
  3097.  
  3098.     /*
  3099.      * Scan over the pattern.  Put a NUL at the end.
  3100.      */
  3101.     pat = skipwhite(pat);
  3102.     cmd = pat;
  3103.     while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\'))
  3104.     cmd++;
  3105.     if (*cmd)
  3106.     *cmd++ = NUL;
  3107.  
  3108.     /*
  3109.      * Check for "nested" flag.
  3110.      */
  3111.     cmd = skipwhite(cmd);
  3112.     if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6]))
  3113.     {
  3114.     nested = TRUE;
  3115.     cmd = skipwhite(cmd + 6);
  3116.     }
  3117.  
  3118.     /*
  3119.      * Find the start of the commands.
  3120.      * Expand <sfile> in it.
  3121.      */
  3122.     if (*cmd != NUL)
  3123.     {
  3124.     cmd = expand_sfile(cmd);
  3125.     if (cmd == NULL)        /* some error */
  3126.         return;
  3127.     need_free = TRUE;
  3128.     }
  3129.  
  3130.     /*
  3131.      * Print header when showing autocommands.
  3132.      */
  3133.     if (!forceit && *cmd == NUL)
  3134.     {
  3135.     /* Highlight title */
  3136.     MSG_PUTS_TITLE("\n--- Auto-Commands ---");
  3137.     }
  3138.  
  3139.     /*
  3140.      * Loop over the events.
  3141.      */
  3142.     last_event = (EVENT_T)-1;        /* for listing the event name */
  3143.     last_group = AUGROUP_ERROR;        /* for listing the group name */
  3144.     if (*arg == '*' || *arg == NUL)
  3145.     {
  3146.     for (event = (EVENT_T)0; event < NUM_EVENTS;
  3147.                         event = (EVENT_T)((int)event + 1))
  3148.         if (do_autocmd_event(event, pat,
  3149.                      nested, cmd, forceit, group) == FAIL)
  3150.         break;
  3151.     }
  3152.     else
  3153.     {
  3154.     while (*arg && !vim_iswhite(*arg))
  3155.         if (do_autocmd_event(event_name2nr(arg, &arg), pat,
  3156.                     nested,    cmd, forceit, group) == FAIL)
  3157.         break;
  3158.     }
  3159.  
  3160.     if (need_free)
  3161.     vim_free(cmd);
  3162. }
  3163.  
  3164. /*
  3165.  * Find the group ID in a ":autocmd" or ":doautocmd" argument.
  3166.  * The "argp" argument is advanced to the following argument.
  3167.  *
  3168.  * Returns the group ID, AUGROUP_ERROR for error (out of memory).
  3169.  */
  3170.     static int
  3171. au_get_grouparg(argp)
  3172.     char_u    **argp;
  3173. {
  3174.     char_u    *group_name;
  3175.     char_u    *p;
  3176.     char_u    *arg = *argp;
  3177.     int        group = AUGROUP_ALL;
  3178.  
  3179.     p = skiptowhite(arg);
  3180.     if (p > arg)
  3181.     {
  3182.     group_name = vim_strnsave(arg, (int)(p - arg));
  3183.     if (group_name == NULL)        /* out of memory */
  3184.         return AUGROUP_ERROR;
  3185.     group = au_find_group(group_name);
  3186.     if (group == AUGROUP_ERROR)
  3187.         group = AUGROUP_ALL;    /* no match, use all groups */
  3188.     else
  3189.         *argp = skipwhite(p);    /* match, skip over group name */
  3190.     vim_free(group_name);
  3191.     }
  3192.     return group;
  3193. }
  3194.  
  3195. /*
  3196.  * do_autocmd() for one event.
  3197.  * If *pat == NUL do for all patterns.
  3198.  * If *cmd == NUL show entries.
  3199.  * If forceit == TRUE delete entries.
  3200.  * If group is not AUGROUP_ALL, only use this group.
  3201.  */
  3202.     static int
  3203. do_autocmd_event(event, pat, nested, cmd, forceit, group)
  3204.     EVENT_T    event;
  3205.     char_u    *pat;
  3206.     int        nested;
  3207.     char_u    *cmd;
  3208.     int        forceit;
  3209.     int        group;
  3210. {
  3211.     AutoPat    *ap;
  3212.     AutoPat    **prev_ap;
  3213.     AutoCmd    *ac;
  3214.     AutoCmd    **prev_ac;
  3215.     int        brace_level;
  3216.     char_u    *endpat;
  3217.     int        len;
  3218.  
  3219.     /*
  3220.      * Show or delete all patterns for an event.
  3221.      */
  3222.     if (*pat == NUL)
  3223.     {
  3224.     for (ap = first_autopat[event]; ap != NULL; ap = ap->next)
  3225.     {
  3226.         if (forceit)  /* delete the AutoPat, if it's in the current group */
  3227.         {
  3228.         if (ap->group == (group == AUGROUP_ALL ? current_augroup
  3229.                                : group))
  3230.             au_remove_pat(ap);
  3231.         }
  3232.         else if (group == AUGROUP_ALL || ap->group == group)
  3233.         show_autocmd(ap, event);
  3234.     }
  3235.     }
  3236.  
  3237.     /*
  3238.      * Loop through all the specified patterns.
  3239.      */
  3240.     for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
  3241.     {
  3242.     /*
  3243.      * Find end of the pattern.
  3244.      * Watch out for a comma in braces, like "*.\{obj,o\}".
  3245.      */
  3246.     brace_level = 0;
  3247.     for (endpat = pat; *endpat && (*endpat != ',' || brace_level
  3248.                          || endpat[-1] == '\\'); ++endpat)
  3249.     {
  3250.         if (*endpat == '{')
  3251.         brace_level++;
  3252.         else if (*endpat == '}')
  3253.         brace_level--;
  3254.     }
  3255.     if (pat == endpat)        /* ignore single comma */
  3256.         continue;
  3257.  
  3258.     /*
  3259.      * Find AutoPat entries with this pattern.
  3260.      */
  3261.     prev_ap = &first_autopat[event];
  3262.     while ((ap = *prev_ap) != NULL)
  3263.     {
  3264.         if (ap->pat != NULL)
  3265.         {
  3266.         /* Accept a pattern when:
  3267.          * - a group was specified and it's that group, or a group was
  3268.          *   not specified and it's the current group, or a group was
  3269.          *   not specified and we are listing
  3270.          * - the length of the pattern matches
  3271.          * - the pattern matches
  3272.          */
  3273.         len = STRLEN(ap->pat);
  3274.         if ((ap->group == (group == AUGROUP_ALL ? current_augroup
  3275.                             : group)
  3276.                || (group == AUGROUP_ALL && !forceit && *cmd == NUL))
  3277.             && len == endpat - pat
  3278.             && STRNCMP(pat, ap->pat, len) == 0)
  3279.         {
  3280.             /*
  3281.              * Remove existing autocommands.
  3282.              * If adding any new autocmd's for this AutoPat, don't
  3283.              * delete the pattern from the autopat list, append to
  3284.              * this list.
  3285.              */
  3286.             if (forceit)
  3287.             {
  3288.             if (*cmd != NUL && ap->next == NULL)
  3289.             {
  3290.                 au_remove_cmds(ap);
  3291.                 break;
  3292.             }
  3293.             au_remove_pat(ap);
  3294.             }
  3295.  
  3296.             /*
  3297.              * Show autocmd's for this autopat
  3298.              */
  3299.             else if (*cmd == NUL)
  3300.             show_autocmd(ap, event);
  3301.  
  3302.             /*
  3303.              * Add autocmd to this autopat, if it's the last one.
  3304.              */
  3305.             else if (ap->next == NULL)
  3306.             break;
  3307.         }
  3308.         }
  3309.         prev_ap = &ap->next;
  3310.     }
  3311.  
  3312.     /*
  3313.      * Add a new command.
  3314.      */
  3315.     if (*cmd != NUL)
  3316.     {
  3317.         /*
  3318.          * If the pattern we want to add a command to does appear at the
  3319.          * end of the list (or not is not in the list at all), add the
  3320.          * pattern at the end of the list.
  3321.          */
  3322.         if (ap == NULL)
  3323.         {
  3324.         ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat));
  3325.         if (ap == NULL)
  3326.             return FAIL;
  3327.         ap->pat = vim_strnsave(pat, (int)(endpat - pat));
  3328.         if (ap->pat == NULL)
  3329.         {
  3330.             vim_free(ap);
  3331.             return FAIL;
  3332.         }
  3333.         ap->reg_pat = file_pat_to_reg_pat(pat, endpat, &ap->allow_dirs);
  3334.         if (ap->reg_pat == NULL)
  3335.         {
  3336.             vim_free(ap->pat);
  3337.             vim_free(ap);
  3338.             return FAIL;
  3339.         }
  3340.         ap->cmds = NULL;
  3341.         *prev_ap = ap;
  3342.         ap->next = NULL;
  3343.         if (group == AUGROUP_ALL)
  3344.             ap->group = current_augroup;
  3345.         else
  3346.             ap->group = group;
  3347.         }
  3348.  
  3349.         /*
  3350.          * Add the autocmd at the end of the AutoCmd list.
  3351.          */
  3352.         prev_ac = &(ap->cmds);
  3353.         while ((ac = *prev_ac) != NULL)
  3354.         prev_ac = &ac->next;
  3355.         ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd));
  3356.         if (ac == NULL)
  3357.         return FAIL;
  3358.         ac->cmd = vim_strsave(cmd);
  3359.         if (ac->cmd == NULL)
  3360.         {
  3361.         vim_free(ac);
  3362.         return FAIL;
  3363.         }
  3364.         ac->next = NULL;
  3365.         *prev_ac = ac;
  3366.         ac->nested = nested;
  3367.     }
  3368.     }
  3369.  
  3370.     au_cleanup();    /* may really delete removed patterns/commands now */
  3371.     return OK;
  3372. }
  3373.  
  3374. /*
  3375.  * Implementation of ":doautocmd [group] event [fname]".
  3376.  * Return OK for success, FAIL for failure;
  3377.  */
  3378.     int
  3379. do_doautocmd(arg, do_msg)
  3380.     char_u    *arg;
  3381.     int        do_msg;        /* give message for no matching autocmds? */
  3382. {
  3383.     char_u    *fname;
  3384.     int        nothing_done = TRUE;
  3385.     int        group;
  3386.  
  3387.     /*
  3388.      * Check for a legal group name.  If not, use AUGROUP_ALL.
  3389.      */
  3390.     group = au_get_grouparg(&arg);
  3391.     if (arg == NULL)        /* out of memory */
  3392.     return FAIL;
  3393.  
  3394.     if (*arg == '*')
  3395.     {
  3396.     EMSG("Can't execute autocommands for ALL events");
  3397.     return FAIL;
  3398.     }
  3399.  
  3400.     /*
  3401.      * Scan over the events.
  3402.      * If we find an illegal name, return here, don't do anything.
  3403.      */
  3404.     fname = find_end_event(arg);
  3405.     if (fname == NULL)
  3406.     return FAIL;
  3407.  
  3408.     fname = skipwhite(fname);
  3409.  
  3410.     /*
  3411.      * Loop over the events.
  3412.      */
  3413.     while (*arg && !vim_iswhite(*arg))
  3414.     if (apply_autocmds_group(event_name2nr(arg, &arg),
  3415.                             fname, NULL, TRUE, group))
  3416.         nothing_done = FALSE;
  3417.  
  3418.     if (nothing_done && do_msg)
  3419.     MSG("No matching autocommands");
  3420.  
  3421.     return OK;
  3422. }
  3423.  
  3424. /*
  3425.  * ":doautoall" command: execute autocommands for each loaded buffer.
  3426.  */
  3427.     void
  3428. do_autoall(arg)
  3429.     char_u    *arg;
  3430. {
  3431.     BUF        *save_buf = NULL;
  3432.     WIN        *win;
  3433.     WIN        *save_curwin = NULL;
  3434.     int        retval;
  3435.     FPOS    save_cursor;
  3436.     linenr_t    save_topline = 0;
  3437.     int        len;
  3438.  
  3439.     save_cursor.lnum = 0;   /* init for gcc */
  3440.     save_cursor.col = 0;
  3441.  
  3442.     /*
  3443.      * This is a bit tricky: For some commands curwin->w_buffer needs to be
  3444.      * equal to curbuf, but for some buffers there may not be a window.
  3445.      * So we change the buffer for the current window for a moment.  This
  3446.      * gives problems when the autocommands make changes to the list of
  3447.      * buffers or windows...
  3448.      */
  3449.     for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
  3450.     {
  3451.     if (curbuf->b_ml.ml_mfp != NULL)
  3452.     {
  3453.         for (win = firstwin; win != NULL; win = win->w_next)
  3454.         if (win->w_buffer == curbuf)
  3455.             break;
  3456.         /* if there is a window for this buffer, make it the curwin */
  3457.         if (win != NULL)
  3458.         {
  3459.         save_curwin = curwin;
  3460.         curwin = win;
  3461.         }
  3462.         else
  3463.         {
  3464.         /* if there is no window for this buffer, use curwin */
  3465.         --curwin->w_buffer->b_nwindows;
  3466.         save_buf = curwin->w_buffer;
  3467.         curwin->w_buffer = curbuf;
  3468.         ++curwin->w_buffer->b_nwindows;
  3469.  
  3470.         /* set cursor and topline to safe values */
  3471.         save_cursor = curwin->w_cursor;
  3472.         curwin->w_cursor.lnum = 1;
  3473.         curwin->w_cursor.col = 0;
  3474.         save_topline = curwin->w_topline;
  3475.         curwin->w_topline = 1;
  3476.         }
  3477.         retval = do_doautocmd(arg, FALSE);
  3478.         do_modelines();
  3479.         if (win != NULL)        /* restore curwin */
  3480.         {
  3481.         if (win_valid(save_curwin))
  3482.             curwin = save_curwin;
  3483.         }
  3484.         else            /* restore buffer for curwin */
  3485.         {
  3486.         if (buf_valid(save_buf))
  3487.         {
  3488.             --curwin->w_buffer->b_nwindows;
  3489.             curwin->w_buffer = save_buf;
  3490.             ++save_buf->b_nwindows;
  3491.             if (save_cursor.lnum <= save_buf->b_ml.ml_line_count)
  3492.             {
  3493.             curwin->w_cursor = save_cursor;
  3494.             len = STRLEN(ml_get_buf(save_buf,
  3495.                            curwin->w_cursor.lnum, FALSE));
  3496.             if (len == 0)
  3497.                 curwin->w_cursor.col = 0;
  3498.             else if ((int)curwin->w_cursor.col >= len)
  3499.                 curwin->w_cursor.col = len - 1;
  3500.             }
  3501.             else
  3502.             {
  3503.             curwin->w_cursor.lnum = save_buf->b_ml.ml_line_count;
  3504.             curwin->w_cursor.col = 0;
  3505.             }
  3506.             /* check topline < line_count, in case lines got deleted */
  3507.             if (save_topline <= save_buf->b_ml.ml_line_count)
  3508.             curwin->w_topline = save_topline;
  3509.             else
  3510.             curwin->w_topline = save_buf->b_ml.ml_line_count;
  3511.         }
  3512.         }
  3513.         if (retval == FAIL)
  3514.         break;
  3515.     }
  3516.     }
  3517.  
  3518.     curbuf = curwin->w_buffer;
  3519.     adjust_cursor();        /* just in case lines got deleted */
  3520. }
  3521.  
  3522. static int    autocmd_nested = FALSE;
  3523.  
  3524. /*
  3525.  * Execute autocommands for "event" and file name "fname".
  3526.  * Return TRUE if some commands were executed.
  3527.  */
  3528.     int
  3529. apply_autocmds(event, fname, fname_io, force)
  3530.     EVENT_T    event;
  3531.     char_u    *fname;        /* NULL or empty means use actual file name */
  3532.     char_u    *fname_io;  /* fname to use for <afile> on cmdline */
  3533.     int        force;        /* when TRUE, ignore autocmd_busy */
  3534. {
  3535.     return apply_autocmds_group(event, fname, fname_io, force, AUGROUP_ALL);
  3536. }
  3537.  
  3538.     static int
  3539. apply_autocmds_group(event, fname, fname_io, force, group)
  3540.     EVENT_T    event;
  3541.     char_u    *fname;        /* NULL or empty means use actual file name */
  3542.     char_u    *fname_io;  /* fname to use for <afile> on cmdline */
  3543.     int        force;        /* when TRUE, ignore autocmd_busy */
  3544.     int        group;        /* group ID, or AUGROUP_ALL */
  3545. {
  3546.     char_u        *sfname = NULL;    /* short file name */
  3547.     char_u        *tail;
  3548.     int            temp;
  3549.     int            save_changed = curbuf->b_changed;
  3550.     BUF            *old_curbuf = curbuf;
  3551.     int            retval = FALSE;
  3552.     char_u        *save_sourcing_name = sourcing_name;
  3553.     char_u        *save_autocmd_fname = autocmd_fname;
  3554.     int            save_autocmd_busy = autocmd_busy;
  3555.     int            save_autocmd_nested = autocmd_nested;
  3556.     static int        nesting = 0;
  3557.     AutoPatCmd        patcmd;
  3558.     AutoPat        *ap;
  3559.  
  3560.     /*
  3561.      * When autocommands are busy, new autocommands are only executed when
  3562.      * explicitly enabled with the "nested" flag.
  3563.      */
  3564.     if (autocmd_busy && !(force || autocmd_nested))
  3565.     return retval;
  3566.  
  3567.     /*
  3568.      * Ignore events in 'eventignore'.
  3569.      */
  3570.     if (event_ignored(event))
  3571.     return retval;
  3572.  
  3573.     /*
  3574.      * Allow nesting of autocommands, but restrict the depth, because it's
  3575.      * possible to create an endless loop.
  3576.      */
  3577.     if (nesting == 10)
  3578.     {
  3579.     EMSG("autocommand nesting too deep");
  3580.     return retval;
  3581.     }
  3582.  
  3583.     /*
  3584.      * Check if these autocommands are disabled.  Used when doing ":all" or
  3585.      * ":ball".
  3586.      */
  3587.     if (    (autocmd_no_enter &&
  3588.         (event == EVENT_WINENTER || event == EVENT_BUFENTER)) ||
  3589.         (autocmd_no_leave &&
  3590.         (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
  3591.     return retval;
  3592.  
  3593.     /*
  3594.      * Set the file name to be used for <afile>.
  3595.      */
  3596.     if (fname_io == NULL)
  3597.     {
  3598.     if (fname == NULL || *fname == NUL)
  3599.         autocmd_fname = curbuf->b_fname;
  3600.     else
  3601.         autocmd_fname = fname;
  3602.     }
  3603.     else
  3604.     autocmd_fname = fname_io;
  3605.  
  3606.     /*
  3607.      * When the file name is NULL or empty, use the file name of the current
  3608.      * buffer.    Always use the full path of the file name to match with, in
  3609.      * case "allow_dirs" is set.
  3610.      */
  3611.     if (fname == NULL || *fname == NUL)
  3612.     {
  3613.     if (curbuf->b_sfname != NULL)
  3614.         sfname = vim_strsave(curbuf->b_sfname);
  3615.     fname = curbuf->b_ffname;
  3616.     if (fname == NULL)
  3617.         fname = (char_u *)"";
  3618.     fname = vim_strsave(fname);    /* make a copy, so we can change it */
  3619.     }
  3620.     else
  3621.     {
  3622.     sfname = vim_strsave(fname);
  3623.     fname = FullName_save(fname, FALSE);
  3624.     }
  3625.     if (fname == NULL)        /* out of memory */
  3626.     return FALSE;
  3627.  
  3628. #ifdef BACKSLASH_IN_FILENAME
  3629.     /*
  3630.      * Replace all backslashes with forward slashes.  This makes the
  3631.      * autocommand patterns portable between Unix and MS-DOS.
  3632.      */
  3633.     {
  3634.     char_u        *p;
  3635.  
  3636.     if (sfname != NULL)
  3637.     {
  3638.         for (p = sfname; *p; ++p)
  3639.         if (*p == '\\')
  3640.             *p = '/';
  3641.     }
  3642.     for (p = fname; *p; ++p)
  3643.         if (*p == '\\')
  3644.         *p = '/';
  3645.     }
  3646. #endif
  3647.  
  3648.     /* Don't redraw while doing auto commands. */
  3649.     temp = RedrawingDisabled;
  3650.     RedrawingDisabled = TRUE;
  3651.     sourcing_name = NULL;    /* don't free this one */
  3652.  
  3653.     /*
  3654.      * When starting to execute autocommands, save the search patterns.
  3655.      */
  3656.     if (!autocmd_busy)
  3657.     {
  3658.     save_search_patterns();
  3659.     saveRedobuff();
  3660.     }
  3661.  
  3662.     /*
  3663.      * Note that we are applying autocmds.  Some commands need to know.
  3664.      */
  3665.     autocmd_busy = TRUE;
  3666.     ++nesting;
  3667.  
  3668.     tail = gettail(fname);
  3669.  
  3670.     /* Find first autocommand that matches */
  3671.     patcmd.curpat = first_autopat[event];
  3672.     patcmd.nextcmd = NULL;
  3673.     patcmd.group = group;
  3674.     patcmd.fname = fname;
  3675.     patcmd.sfname = sfname;
  3676.     patcmd.tail = tail;
  3677.     patcmd.event = event;
  3678.     auto_next_pat(&patcmd, FALSE);
  3679.  
  3680.     /* found one, start executing the autocommands */
  3681.     if (patcmd.curpat != NULL)
  3682.     {
  3683.     retval = TRUE;
  3684.     /* mark the last pattern, to avoid an endless loop when more patterns
  3685.      * are added when executing autocommands */
  3686.     for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next)
  3687.         ap->last = FALSE;
  3688.     ap->last = TRUE;
  3689.     check_lnums(TRUE);    /* make sure cursor and topline are valid */
  3690.     do_cmdline(NULL, getnextac, (void *)&patcmd,
  3691.                      DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
  3692.     }
  3693.  
  3694.     RedrawingDisabled = temp;
  3695.     autocmd_busy = save_autocmd_busy;
  3696.     autocmd_nested = save_autocmd_nested;
  3697.     sourcing_name = save_sourcing_name;
  3698.     autocmd_fname = save_autocmd_fname;
  3699.     vim_free(fname);
  3700.     vim_free(sfname);
  3701.     --nesting;
  3702.  
  3703.     /*
  3704.      * When stopping to execute autocommands, restore the search patterns and
  3705.      * the redo buffer.
  3706.      */
  3707.     if (!autocmd_busy)
  3708.     {
  3709.     restore_search_patterns();
  3710.     restoreRedobuff();
  3711.     }
  3712.  
  3713.     /*
  3714.      * Some events don't set or reset the Changed flag.
  3715.      * Check if still in the same buffer!
  3716.      */
  3717.     if (curbuf == old_curbuf &&
  3718.         (event == EVENT_BUFREADPOST || event == EVENT_BUFWRITEPOST ||
  3719.         event == EVENT_FILEAPPENDPOST || event == EVENT_VIMLEAVE))
  3720.     curbuf->b_changed = save_changed;
  3721.  
  3722.     au_cleanup();    /* may really delete removed patterns/commands now */
  3723.     return retval;
  3724. }
  3725.  
  3726. /*
  3727.  * Find next autocommand pattern that matches.
  3728.  */
  3729.     static void
  3730. auto_next_pat(apc, stop_at_last)
  3731.     AutoPatCmd    *apc;
  3732.     int        stop_at_last;        /* stop when 'last' flag is set */
  3733. {
  3734.     AutoPat        *ap;
  3735.     vim_regexp        *prog;
  3736.     AutoCmd        *cp;
  3737.     char_u        *name;
  3738.  
  3739.     vim_free(sourcing_name);
  3740.     sourcing_name = NULL;
  3741.  
  3742.     for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
  3743.     {
  3744.     apc->curpat = NULL;
  3745.  
  3746.     /* only use a pattern when it has not been removed, has commands and
  3747.      * the group matches */
  3748.     if (ap->pat != NULL && ap->cmds != NULL
  3749.         && (apc->group == AUGROUP_ALL || apc->group == ap->group))
  3750.     {
  3751. #ifdef CASE_INSENSITIVE_FILENAME
  3752.         reg_ic = TRUE;            /* Always ignore case */
  3753. #else
  3754.         reg_ic = FALSE;            /* Don't ever ignore case */
  3755. #endif
  3756.         prog = vim_regcomp(ap->reg_pat, TRUE);    /* Always use magic */
  3757.  
  3758.         /*
  3759.          * Try for a match with the pattern with:
  3760.          * 1. the full file name, when the pattern has a '/'.
  3761.          * 2. the short file name, when the pattern has a '/'.
  3762.          * 3. the tail of the file name, when the pattern has no '/'.
  3763.          */
  3764.         if (   prog != NULL
  3765.         && ((ap->allow_dirs
  3766.             && (vim_regexec(prog, apc->fname, TRUE)
  3767.                 || (apc->sfname != NULL
  3768.                 && vim_regexec(prog, apc->sfname, TRUE))))
  3769.             || (!ap->allow_dirs
  3770.             && vim_regexec(prog, apc->tail, TRUE))))
  3771.         {
  3772.         name = event_nr2name(apc->event);
  3773.         sourcing_name = alloc((unsigned)(STRLEN(name)
  3774.                              + STRLEN(ap->pat) + 25));
  3775.         if (sourcing_name != NULL)
  3776.         {
  3777.             sprintf((char *)sourcing_name,
  3778.                 "%s Auto commands for \"%s\"",
  3779.                            (char *)name, (char *)ap->pat);
  3780.             if (p_verbose >= 8)
  3781.             smsg((char_u *)"Executing %s", sourcing_name);
  3782.         }
  3783.  
  3784.         apc->curpat = ap;
  3785.         apc->nextcmd = ap->cmds;
  3786.         /* mark last command */
  3787.         for (cp = ap->cmds; cp->next != NULL; cp = cp->next)
  3788.             cp->last = FALSE;
  3789.         cp->last = TRUE;
  3790.         }
  3791.         vim_free(prog);
  3792.         line_breakcheck();
  3793.         if (apc->curpat != NULL)        /* found a match */
  3794.         break;
  3795.     }
  3796.     if (stop_at_last && ap->last)
  3797.         break;
  3798.     }
  3799. }
  3800.  
  3801. /*
  3802.  * Get next autocommand command.
  3803.  * Called by do_cmdline() to get the next line for ":if".
  3804.  * Returns allocated string, or NULL for end of autocommands.
  3805.  */
  3806. /* ARGSUSED */
  3807.     static char_u *
  3808. getnextac(c, cookie, indent)
  3809.     int        c;            /* not used */
  3810.     void    *cookie;
  3811.     int        indent;        /* not used */
  3812. {
  3813.     AutoPatCmd        *acp = (AutoPatCmd *)cookie;
  3814.     char_u        *retval;
  3815.  
  3816.     /* repeat until we find an autocommand to execute */
  3817.     for (;;)
  3818.     {
  3819.     /* skip removed commands */
  3820.     while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL)
  3821.         if (acp->nextcmd->last)
  3822.         acp->nextcmd = NULL;
  3823.         else
  3824.         acp->nextcmd = acp->nextcmd->next;
  3825.  
  3826.     if (acp->nextcmd != NULL)
  3827.         break;
  3828.  
  3829.     /* at end of commands, find next pattern that matches */
  3830.     if (acp->curpat->last)
  3831.         acp->curpat = NULL;
  3832.     else
  3833.         acp->curpat = acp->curpat->next;
  3834.     if (acp->curpat != NULL)
  3835.         auto_next_pat(acp, TRUE);
  3836.     if (acp->curpat == NULL)
  3837.         return NULL;
  3838.     }
  3839.  
  3840.     if (p_verbose >= 9)
  3841.     {
  3842.     msg_scroll = TRUE;        /* always scroll up, don't overwrite */
  3843.     smsg((char_u *)"autocommand %s", acp->nextcmd->cmd);
  3844.     msg_puts((char_u *)"\n");   /* don't overwrite this either */
  3845.     cmdline_row = msg_row;
  3846.     }
  3847.     retval = vim_strsave(acp->nextcmd->cmd);
  3848.     autocmd_nested = acp->nextcmd->nested;
  3849.     if (acp->nextcmd->last)
  3850.     acp->nextcmd = NULL;
  3851.     else
  3852.     acp->nextcmd = acp->nextcmd->next;
  3853.     return retval;
  3854. }
  3855.  
  3856. static int include_groups = FALSE;
  3857.  
  3858.     char_u  *
  3859. set_context_in_autocmd(arg, doautocmd)
  3860.     char_u  *arg;
  3861.     int        doautocmd;        /* TRUE for :doautocmd, FALSE for :autocmd */
  3862. {
  3863.     char_u  *p;
  3864.     int        group;
  3865.  
  3866.     /* check for a group name, skip it if present */
  3867.     include_groups = FALSE;
  3868.     group = au_get_grouparg(&arg);
  3869.     if (group == AUGROUP_ERROR)
  3870.     return NULL;
  3871.  
  3872.     /* skip over event name */
  3873.     for (p = arg; *p && !vim_iswhite(*p); ++p)
  3874.     if (*p == ',')
  3875.         arg = p + 1;
  3876.     if (*p == NUL)
  3877.     {
  3878.     if (group == AUGROUP_ALL)
  3879.         include_groups = TRUE;
  3880.     expand_context = EXPAND_EVENTS;        /* expand event name */
  3881.     expand_pattern = arg;
  3882.     return NULL;
  3883.     }
  3884.  
  3885.     /* skip over pattern */
  3886.     arg = skipwhite(p);
  3887.     while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\\'))
  3888.     arg++;
  3889.     if (*arg)
  3890.     return arg;                /* expand (next) command */
  3891.  
  3892.     if (doautocmd)
  3893.     expand_context = EXPAND_FILES;        /* expand file names */
  3894.     else
  3895.     expand_context = EXPAND_NOTHING;    /* pattern is not expanded */
  3896.     return NULL;
  3897. }
  3898.  
  3899. /*
  3900.  * Function given to ExpandGeneric() to obtain the list of event names.
  3901.  */
  3902.     char_u *
  3903. get_event_name(idx)
  3904.     int        idx;
  3905. {
  3906.     if (idx < augroups.ga_len)        /* First list group names, if wanted */
  3907.     {
  3908.     if (!include_groups || AUGROUP_NAME(idx) == NULL)
  3909.         return (char_u *)"";    /* skip deleted entries */
  3910.     return AUGROUP_NAME(idx);    /* return a name */
  3911.     }
  3912.     return (char_u *)event_names[idx - augroups.ga_len].name;
  3913. }
  3914.  
  3915. #endif    /* AUTOCMD */
  3916.  
  3917. /*
  3918.  * Convert the given pattern "pat" which has shell style wildcards in it, into
  3919.  * a regular expression, and return the result.  If there is a directory path
  3920.  * separator to be matched, then TRUE is put in allow_dirs, otherwise FALSE is
  3921.  * put there -- webb.
  3922.  */
  3923.     char_u *
  3924. file_pat_to_reg_pat(pat, pat_end, allow_dirs)
  3925.     char_u  *pat;
  3926.     char_u  *pat_end;        /* first char after pattern */
  3927.     char    *allow_dirs;    /* Result passed back out in here */
  3928. {
  3929.     int        size;
  3930.     char_u    *endp;
  3931.     char_u    *reg_pat;
  3932.     char_u    *p;
  3933.     int        i;
  3934.     int        nested = 0;
  3935.     int        add_dollar = TRUE;
  3936.  
  3937.     if (allow_dirs != NULL)
  3938.     *allow_dirs = FALSE;
  3939.  
  3940.     size = 2;        /* '^' at start, '$' at end */
  3941.     for (p = pat; p < pat_end; p++)
  3942.     {
  3943.     switch (*p)
  3944.     {
  3945.         case '*':
  3946.         case '.':
  3947.         case ',':
  3948.         case '{':
  3949.         case '}':
  3950.         case '~':
  3951. #ifdef BACKSLASH_IN_FILENAME
  3952.         case '\\':
  3953. #endif
  3954.         size += 2;
  3955.         break;
  3956.         default:
  3957.         size++;
  3958.         break;
  3959.     }
  3960.     }
  3961.     reg_pat = alloc(size + 1);
  3962.     if (reg_pat == NULL)
  3963.     return NULL;
  3964.     i = 0;
  3965.     if (pat[0] == '*')
  3966.     while (pat[0] == '*' && pat < pat_end - 1)
  3967.         pat++;
  3968.     else
  3969.     reg_pat[i++] = '^';
  3970.     endp = pat_end - 1;
  3971.     if (*endp == '*')
  3972.     {
  3973.     while (endp - pat > 0 && *endp == '*')
  3974.         endp--;
  3975.     add_dollar = FALSE;
  3976.     }
  3977.     for (p = pat; *p && nested >= 0 && p <= endp; p++)
  3978.     {
  3979.     switch (*p)
  3980.     {
  3981.         case '*':
  3982.         reg_pat[i++] = '.';
  3983.         reg_pat[i++] = '*';
  3984.         break;
  3985.         case '.':
  3986.         case '~':
  3987.         reg_pat[i++] = '\\';
  3988.         reg_pat[i++] = *p;
  3989.         break;
  3990.         case '?':
  3991.         reg_pat[i++] = '.';
  3992.         break;
  3993.         case '\\':
  3994.         if (p[1] == NUL)
  3995.             break;
  3996. #ifdef BACKSLASH_IN_FILENAME
  3997.         /* translate "\x" to "\\x", "\*" to "\\.*", and "\?" to "\\." */
  3998.         if (vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?')
  3999.         {
  4000.             reg_pat[i++] = '\\';
  4001.             reg_pat[i++] = '\\';
  4002.             if (allow_dirs != NULL)
  4003.             *allow_dirs = TRUE;
  4004.             break;
  4005.         }
  4006.         ++p;
  4007. #else
  4008.         if (*++p == '?')
  4009.             reg_pat[i++] = '?';
  4010.         else
  4011. #endif
  4012.             if (*p == ',')
  4013.             reg_pat[i++] = ',';
  4014.             else
  4015.             {
  4016.             if (allow_dirs != NULL && vim_ispathsep(*p))
  4017.                 *allow_dirs = TRUE;
  4018.             reg_pat[i++] = '\\';
  4019.             reg_pat[i++] = *p;
  4020.             }
  4021.         break;
  4022.         case '{':
  4023.         reg_pat[i++] = '\\';
  4024.         reg_pat[i++] = '(';
  4025.         nested++;
  4026.         break;
  4027.         case '}':
  4028.         reg_pat[i++] = '\\';
  4029.         reg_pat[i++] = ')';
  4030.         --nested;
  4031.         break;
  4032.         case ',':
  4033.         if (nested)
  4034.         {
  4035.             reg_pat[i++] = '\\';
  4036.             reg_pat[i++] = '|';
  4037.         }
  4038.         else
  4039.             reg_pat[i++] = ',';
  4040.         break;
  4041.         default:
  4042.         if (allow_dirs != NULL && vim_ispathsep(*p))
  4043.             *allow_dirs = TRUE;
  4044.         reg_pat[i++] = *p;
  4045.         break;
  4046.     }
  4047.     }
  4048.     if (add_dollar)
  4049.     reg_pat[i++] = '$';
  4050.     reg_pat[i] = NUL;
  4051.     if (nested != 0)
  4052.     {
  4053.     if (nested < 0)
  4054.         EMSG("Missing {.");
  4055.     else
  4056.         EMSG("Missing }.");
  4057.     vim_free(reg_pat);
  4058.     reg_pat = NULL;
  4059.     }
  4060.     return reg_pat;
  4061. }
  4062.